1b5a8f767SHajimu UMEMOTO /* $KAME: des_locl.h,v 1.7 2001/09/10 04:03:58 itojun Exp $ */ 2686cdd19SJun-ichiro itojun Hagino 3b5a8f767SHajimu UMEMOTO /* crypto/des/des_locl.h */ 4b5a8f767SHajimu UMEMOTO /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au) 56a800098SYoshinobu Inoue * All rights reserved. 66a800098SYoshinobu Inoue * 76a800098SYoshinobu Inoue * This file is part of an SSL implementation written 86a800098SYoshinobu Inoue * by Eric Young (eay@mincom.oz.au). 96a800098SYoshinobu Inoue * The implementation was written so as to conform with Netscapes SSL 106a800098SYoshinobu Inoue * specification. This library and applications are 116a800098SYoshinobu Inoue * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE 126a800098SYoshinobu Inoue * as long as the following conditions are aheared to. 136a800098SYoshinobu Inoue * 146a800098SYoshinobu Inoue * Copyright remains Eric Young's, and as such any Copyright notices in 156a800098SYoshinobu Inoue * the code are not to be removed. If this code is used in a product, 166a800098SYoshinobu Inoue * Eric Young should be given attribution as the author of the parts used. 176a800098SYoshinobu Inoue * This can be in the form of a textual message at program startup or 186a800098SYoshinobu Inoue * in documentation (online or textual) provided with the package. 196a800098SYoshinobu Inoue * 206a800098SYoshinobu Inoue * Redistribution and use in source and binary forms, with or without 216a800098SYoshinobu Inoue * modification, are permitted provided that the following conditions 226a800098SYoshinobu Inoue * are met: 236a800098SYoshinobu Inoue * 1. Redistributions of source code must retain the copyright 246a800098SYoshinobu Inoue * notice, this list of conditions and the following disclaimer. 256a800098SYoshinobu Inoue * 2. Redistributions in binary form must reproduce the above copyright 266a800098SYoshinobu Inoue * notice, this list of conditions and the following disclaimer in the 276a800098SYoshinobu Inoue * documentation and/or other materials provided with the distribution. 286a800098SYoshinobu Inoue * 3. All advertising materials mentioning features or use of this software 296a800098SYoshinobu Inoue * must display the following acknowledgement: 306a800098SYoshinobu Inoue * This product includes software developed by Eric Young (eay@mincom.oz.au) 316a800098SYoshinobu Inoue * 326a800098SYoshinobu Inoue * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 336a800098SYoshinobu Inoue * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 346a800098SYoshinobu Inoue * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 356a800098SYoshinobu Inoue * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 366a800098SYoshinobu Inoue * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 376a800098SYoshinobu Inoue * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 386a800098SYoshinobu Inoue * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 396a800098SYoshinobu Inoue * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 406a800098SYoshinobu Inoue * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 416a800098SYoshinobu Inoue * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 426a800098SYoshinobu Inoue * SUCH DAMAGE. 436a800098SYoshinobu Inoue * 446a800098SYoshinobu Inoue * The licence and distribution terms for any publically available version or 456a800098SYoshinobu Inoue * derivative of this code cannot be changed. i.e. this code cannot simply be 466a800098SYoshinobu Inoue * copied and put under another distribution licence 476a800098SYoshinobu Inoue * [including the GNU Public Licence.] 486a800098SYoshinobu Inoue */ 496a800098SYoshinobu Inoue 506a800098SYoshinobu Inoue #ifndef HEADER_DES_LOCL_H 516a800098SYoshinobu Inoue #define HEADER_DES_LOCL_H 526a800098SYoshinobu Inoue 536a800098SYoshinobu Inoue #include <crypto/des/des.h> 546a800098SYoshinobu Inoue 556a800098SYoshinobu Inoue #undef DES_PTR 566a800098SYoshinobu Inoue 576a800098SYoshinobu Inoue #ifdef __STDC__ 586a800098SYoshinobu Inoue #undef NOPROTO 596a800098SYoshinobu Inoue #endif 606a800098SYoshinobu Inoue 616a800098SYoshinobu Inoue #define ITERATIONS 16 626a800098SYoshinobu Inoue #define HALF_ITERATIONS 8 636a800098SYoshinobu Inoue 646a800098SYoshinobu Inoue /* used in des_read and des_write */ 656a800098SYoshinobu Inoue #define MAXWRITE (1024*16) 666a800098SYoshinobu Inoue #define BSIZE (MAXWRITE+4) 676a800098SYoshinobu Inoue 686a800098SYoshinobu Inoue #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 696a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))<< 8L, \ 706a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))<<16L, \ 716a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))<<24L) 726a800098SYoshinobu Inoue 736a800098SYoshinobu Inoue /* NOTE - c is not incremented as per c2l */ 746a800098SYoshinobu Inoue #define c2ln(c,l1,l2,n) { \ 756a800098SYoshinobu Inoue c+=n; \ 766a800098SYoshinobu Inoue l1=l2=0; \ 776a800098SYoshinobu Inoue switch (n) { \ 786a800098SYoshinobu Inoue case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ 796a800098SYoshinobu Inoue case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ 806a800098SYoshinobu Inoue case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ 816a800098SYoshinobu Inoue case 5: l2|=((DES_LONG)(*(--(c)))); \ 826a800098SYoshinobu Inoue case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ 836a800098SYoshinobu Inoue case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ 846a800098SYoshinobu Inoue case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ 856a800098SYoshinobu Inoue case 1: l1|=((DES_LONG)(*(--(c)))); \ 866a800098SYoshinobu Inoue } \ 876a800098SYoshinobu Inoue } 886a800098SYoshinobu Inoue 896a800098SYoshinobu Inoue #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 906a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 916a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 926a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 936a800098SYoshinobu Inoue 946a800098SYoshinobu Inoue /* replacements for htonl and ntohl since I have no idea what to do 956a800098SYoshinobu Inoue * when faced with machines with 8 byte longs. */ 966a800098SYoshinobu Inoue #define HDRSIZE 4 976a800098SYoshinobu Inoue 986a800098SYoshinobu Inoue #define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ 996a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))<<16L, \ 1006a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))<< 8L, \ 1016a800098SYoshinobu Inoue l|=((DES_LONG)(*((c)++)))) 1026a800098SYoshinobu Inoue 1036a800098SYoshinobu Inoue #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ 1046a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 1056a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 1066a800098SYoshinobu Inoue *((c)++)=(unsigned char)(((l) )&0xff)) 1076a800098SYoshinobu Inoue 1086a800098SYoshinobu Inoue /* NOTE - c is not incremented as per l2c */ 1096a800098SYoshinobu Inoue #define l2cn(l1,l2,c,n) { \ 1106a800098SYoshinobu Inoue c+=n; \ 1116a800098SYoshinobu Inoue switch (n) { \ 1126a800098SYoshinobu Inoue case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ 1136a800098SYoshinobu Inoue case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ 1146a800098SYoshinobu Inoue case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ 1156a800098SYoshinobu Inoue case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ 1166a800098SYoshinobu Inoue case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ 1176a800098SYoshinobu Inoue case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ 1186a800098SYoshinobu Inoue case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ 1196a800098SYoshinobu Inoue case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ 1206a800098SYoshinobu Inoue } \ 1216a800098SYoshinobu Inoue } 1226a800098SYoshinobu Inoue 1236a800098SYoshinobu Inoue #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) 1246a800098SYoshinobu Inoue 125b5a8f767SHajimu UMEMOTO #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) 126b5a8f767SHajimu UMEMOTO #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ 127b5a8f767SHajimu UMEMOTO u=R^s[S ]; \ 128b5a8f767SHajimu UMEMOTO t=R^s[S+1] 129b5a8f767SHajimu UMEMOTO 1306a800098SYoshinobu Inoue /* The changes to this macro may help or hinder, depending on the 1316a800098SYoshinobu Inoue * compiler and the achitecture. gcc2 always seems to do well :-). 1326a800098SYoshinobu Inoue * Inspired by Dana How <how@isl.stanford.edu> 1336a800098SYoshinobu Inoue * DO NOT use the alternative version on machines with 8 byte longs. 1346a800098SYoshinobu Inoue * It does not seem to work on the Alpha, even when DES_LONG is 4 1356a800098SYoshinobu Inoue * bytes, probably an issue of accessing non-word aligned objects :-( */ 1366a800098SYoshinobu Inoue #ifdef DES_PTR 1376a800098SYoshinobu Inoue 138b5a8f767SHajimu UMEMOTO /* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there 139b5a8f767SHajimu UMEMOTO * is no reason to not xor all the sub items together. This potentially 140b5a8f767SHajimu UMEMOTO * saves a register since things can be xored directly into L */ 141b5a8f767SHajimu UMEMOTO 142b5a8f767SHajimu UMEMOTO #if defined(DES_RISC1) || defined(DES_RISC2) 143b5a8f767SHajimu UMEMOTO #ifdef DES_RISC1 144b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) { \ 145b5a8f767SHajimu UMEMOTO unsigned int u1,u2,u3; \ 146b5a8f767SHajimu UMEMOTO LOAD_DATA(R,S,u,t,E0,E1,u1); \ 147b5a8f767SHajimu UMEMOTO u2=(int)u>>8L; \ 148b5a8f767SHajimu UMEMOTO u1=(int)u&0xfc; \ 149b5a8f767SHajimu UMEMOTO u2&=0xfc; \ 1506a800098SYoshinobu Inoue t=ROTATE(t,4); \ 151b5a8f767SHajimu UMEMOTO u>>=16L; \ 152b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP +u1); \ 153b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ 154b5a8f767SHajimu UMEMOTO u3=(int)(u>>8L); \ 155b5a8f767SHajimu UMEMOTO u1=(int)u&0xfc; \ 156b5a8f767SHajimu UMEMOTO u3&=0xfc; \ 157b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ 158b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ 159b5a8f767SHajimu UMEMOTO u2=(int)t>>8L; \ 160b5a8f767SHajimu UMEMOTO u1=(int)t&0xfc; \ 161b5a8f767SHajimu UMEMOTO u2&=0xfc; \ 162b5a8f767SHajimu UMEMOTO t>>=16L; \ 163b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ 164b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ 165b5a8f767SHajimu UMEMOTO u3=(int)t>>8L; \ 166b5a8f767SHajimu UMEMOTO u1=(int)t&0xfc; \ 167b5a8f767SHajimu UMEMOTO u3&=0xfc; \ 168b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ 169b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x700+u3); } 170b5a8f767SHajimu UMEMOTO #endif /* DES_RISC1 */ 171b5a8f767SHajimu UMEMOTO #ifdef DES_RISC2 172b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) { \ 173b5a8f767SHajimu UMEMOTO unsigned int u1,u2,s1,s2; \ 174b5a8f767SHajimu UMEMOTO LOAD_DATA(R,S,u,t,E0,E1,u1); \ 175b5a8f767SHajimu UMEMOTO u2=(int)u>>8L; \ 176b5a8f767SHajimu UMEMOTO u1=(int)u&0xfc; \ 177b5a8f767SHajimu UMEMOTO u2&=0xfc; \ 178b5a8f767SHajimu UMEMOTO t=ROTATE(t,4); \ 179b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP +u1); \ 180b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ 181b5a8f767SHajimu UMEMOTO s1=(int)(u>>16L); \ 182b5a8f767SHajimu UMEMOTO s2=(int)(u>>24L); \ 183b5a8f767SHajimu UMEMOTO s1&=0xfc; \ 184b5a8f767SHajimu UMEMOTO s2&=0xfc; \ 185b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ 186b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ 187b5a8f767SHajimu UMEMOTO u2=(int)t>>8L; \ 188b5a8f767SHajimu UMEMOTO u1=(int)t&0xfc; \ 189b5a8f767SHajimu UMEMOTO u2&=0xfc; \ 190b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ 191b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ 192b5a8f767SHajimu UMEMOTO s1=(int)(t>>16L); \ 193b5a8f767SHajimu UMEMOTO s2=(int)(t>>24L); \ 194b5a8f767SHajimu UMEMOTO s1&=0xfc; \ 195b5a8f767SHajimu UMEMOTO s2&=0xfc; \ 196b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ 197b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ 198b5a8f767SHajimu UMEMOTO u2=(int)t>>8L; \ 199b5a8f767SHajimu UMEMOTO u1=(int)t&0xfc; \ 200b5a8f767SHajimu UMEMOTO u2&=0xfc; \ 201b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ 202b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ 203b5a8f767SHajimu UMEMOTO s1=(int)(t>>16L); \ 204b5a8f767SHajimu UMEMOTO s2=(int)(t>>24L); \ 205b5a8f767SHajimu UMEMOTO s1&=0xfc; \ 206b5a8f767SHajimu UMEMOTO s2&=0xfc; \ 207b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ 208b5a8f767SHajimu UMEMOTO LL^= *(const DES_LONG *)(des_SP+0x700+s2); } 209b5a8f767SHajimu UMEMOTO #endif /* DES_RISC2 */ 210b5a8f767SHajimu UMEMOTO #else /* DES_RISC1 || DES_RISC2 */ 211b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) { \ 212b5a8f767SHajimu UMEMOTO LOAD_DATA_tmp(R,S,u,t,E0,E1); \ 213b5a8f767SHajimu UMEMOTO t=ROTATE(t,4); \ 214b5a8f767SHajimu UMEMOTO LL^= \ 215b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ 216b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ 217b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ 218b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ 219b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ 220b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ 221b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ 222b5a8f767SHajimu UMEMOTO *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } 223b5a8f767SHajimu UMEMOTO #endif /* DES_RISC1 || DES_RISC2 */ 224b5a8f767SHajimu UMEMOTO #else /* original version */ 225b5a8f767SHajimu UMEMOTO 226b5a8f767SHajimu UMEMOTO #if defined(DES_RISC1) || defined(DES_RISC2) 227b5a8f767SHajimu UMEMOTO #ifdef DES_RISC1 228b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) {\ 229b5a8f767SHajimu UMEMOTO unsigned int u1,u2,u3; \ 230b5a8f767SHajimu UMEMOTO LOAD_DATA(R,S,u,t,E0,E1,u1); \ 231b5a8f767SHajimu UMEMOTO u>>=2L; \ 232b5a8f767SHajimu UMEMOTO t=ROTATE(t,6); \ 233b5a8f767SHajimu UMEMOTO u2=(int)u>>8L; \ 234b5a8f767SHajimu UMEMOTO u1=(int)u&0x3f; \ 235b5a8f767SHajimu UMEMOTO u2&=0x3f; \ 236b5a8f767SHajimu UMEMOTO u>>=16L; \ 237b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[0][u1]; \ 238b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[2][u2]; \ 239b5a8f767SHajimu UMEMOTO u3=(int)u>>8L; \ 240b5a8f767SHajimu UMEMOTO u1=(int)u&0x3f; \ 241b5a8f767SHajimu UMEMOTO u3&=0x3f; \ 242b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[4][u1]; \ 243b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[6][u3]; \ 244b5a8f767SHajimu UMEMOTO u2=(int)t>>8L; \ 245b5a8f767SHajimu UMEMOTO u1=(int)t&0x3f; \ 246b5a8f767SHajimu UMEMOTO u2&=0x3f; \ 247b5a8f767SHajimu UMEMOTO t>>=16L; \ 248b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[1][u1]; \ 249b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[3][u2]; \ 250b5a8f767SHajimu UMEMOTO u3=(int)t>>8L; \ 251b5a8f767SHajimu UMEMOTO u1=(int)t&0x3f; \ 252b5a8f767SHajimu UMEMOTO u3&=0x3f; \ 253b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[5][u1]; \ 254b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[7][u3]; } 255b5a8f767SHajimu UMEMOTO #endif /* DES_RISC1 */ 256b5a8f767SHajimu UMEMOTO #ifdef DES_RISC2 257b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) {\ 258b5a8f767SHajimu UMEMOTO unsigned int u1,u2,s1,s2; \ 259b5a8f767SHajimu UMEMOTO LOAD_DATA(R,S,u,t,E0,E1,u1); \ 260b5a8f767SHajimu UMEMOTO u>>=2L; \ 261b5a8f767SHajimu UMEMOTO t=ROTATE(t,6); \ 262b5a8f767SHajimu UMEMOTO u2=(int)u>>8L; \ 263b5a8f767SHajimu UMEMOTO u1=(int)u&0x3f; \ 264b5a8f767SHajimu UMEMOTO u2&=0x3f; \ 265b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[0][u1]; \ 266b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[2][u2]; \ 267b5a8f767SHajimu UMEMOTO s1=(int)u>>16L; \ 268b5a8f767SHajimu UMEMOTO s2=(int)u>>24L; \ 269b5a8f767SHajimu UMEMOTO s1&=0x3f; \ 270b5a8f767SHajimu UMEMOTO s2&=0x3f; \ 271b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[4][s1]; \ 272b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[6][s2]; \ 273b5a8f767SHajimu UMEMOTO u2=(int)t>>8L; \ 274b5a8f767SHajimu UMEMOTO u1=(int)t&0x3f; \ 275b5a8f767SHajimu UMEMOTO u2&=0x3f; \ 276b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[1][u1]; \ 277b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[3][u2]; \ 278b5a8f767SHajimu UMEMOTO s1=(int)t>>16; \ 279b5a8f767SHajimu UMEMOTO s2=(int)t>>24L; \ 280b5a8f767SHajimu UMEMOTO s1&=0x3f; \ 281b5a8f767SHajimu UMEMOTO s2&=0x3f; \ 282b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[5][s1]; \ 283b5a8f767SHajimu UMEMOTO LL^=des_SPtrans[7][s2]; } 284b5a8f767SHajimu UMEMOTO #endif /* DES_RISC2 */ 285b5a8f767SHajimu UMEMOTO 286b5a8f767SHajimu UMEMOTO #else /* DES_RISC1 || DES_RISC2 */ 287b5a8f767SHajimu UMEMOTO 288b5a8f767SHajimu UMEMOTO #define D_ENCRYPT(LL,R,S) {\ 289b5a8f767SHajimu UMEMOTO LOAD_DATA_tmp(R,S,u,t,E0,E1); \ 290b5a8f767SHajimu UMEMOTO t=ROTATE(t,4); \ 291b5a8f767SHajimu UMEMOTO LL^=\ 292b5a8f767SHajimu UMEMOTO des_SPtrans[0][(u>> 2L)&0x3f]^ \ 293b5a8f767SHajimu UMEMOTO des_SPtrans[2][(u>>10L)&0x3f]^ \ 294b5a8f767SHajimu UMEMOTO des_SPtrans[4][(u>>18L)&0x3f]^ \ 295b5a8f767SHajimu UMEMOTO des_SPtrans[6][(u>>26L)&0x3f]^ \ 296b5a8f767SHajimu UMEMOTO des_SPtrans[1][(t>> 2L)&0x3f]^ \ 297b5a8f767SHajimu UMEMOTO des_SPtrans[3][(t>>10L)&0x3f]^ \ 298b5a8f767SHajimu UMEMOTO des_SPtrans[5][(t>>18L)&0x3f]^ \ 299b5a8f767SHajimu UMEMOTO des_SPtrans[7][(t>>26L)&0x3f]; } 300b5a8f767SHajimu UMEMOTO #endif /* DES_RISC1 || DES_RISC2 */ 301b5a8f767SHajimu UMEMOTO #endif /* DES_PTR */ 3026a800098SYoshinobu Inoue 3036a800098SYoshinobu Inoue /* IP and FP 3046a800098SYoshinobu Inoue * The problem is more of a geometric problem that random bit fiddling. 3056a800098SYoshinobu Inoue 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 3066a800098SYoshinobu Inoue 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 3076a800098SYoshinobu Inoue 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 3086a800098SYoshinobu Inoue 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 3096a800098SYoshinobu Inoue 3106a800098SYoshinobu Inoue 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 3116a800098SYoshinobu Inoue 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 3126a800098SYoshinobu Inoue 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 3136a800098SYoshinobu Inoue 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 3146a800098SYoshinobu Inoue 3156a800098SYoshinobu Inoue The output has been subject to swaps of the form 3166a800098SYoshinobu Inoue 0 1 -> 3 1 but the odd and even bits have been put into 3176a800098SYoshinobu Inoue 2 3 2 0 3186a800098SYoshinobu Inoue different words. The main trick is to remember that 3196a800098SYoshinobu Inoue t=((l>>size)^r)&(mask); 3206a800098SYoshinobu Inoue r^=t; 3216a800098SYoshinobu Inoue l^=(t<<size); 3226a800098SYoshinobu Inoue can be used to swap and move bits between words. 3236a800098SYoshinobu Inoue 3246a800098SYoshinobu Inoue So l = 0 1 2 3 r = 16 17 18 19 3256a800098SYoshinobu Inoue 4 5 6 7 20 21 22 23 3266a800098SYoshinobu Inoue 8 9 10 11 24 25 26 27 3276a800098SYoshinobu Inoue 12 13 14 15 28 29 30 31 3286a800098SYoshinobu Inoue becomes (for size == 2 and mask == 0x3333) 3296a800098SYoshinobu Inoue t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 3306a800098SYoshinobu Inoue 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 3316a800098SYoshinobu Inoue 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 3326a800098SYoshinobu Inoue 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 3336a800098SYoshinobu Inoue 3346a800098SYoshinobu Inoue Thanks for hints from Richard Outerbridge - he told me IP&FP 3356a800098SYoshinobu Inoue could be done in 15 xor, 10 shifts and 5 ands. 3366a800098SYoshinobu Inoue When I finally started to think of the problem in 2D 3376a800098SYoshinobu Inoue I first got ~42 operations without xors. When I remembered 3386a800098SYoshinobu Inoue how to use xors :-) I got it to its final state. 3396a800098SYoshinobu Inoue */ 3406a800098SYoshinobu Inoue #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ 3416a800098SYoshinobu Inoue (b)^=(t),\ 3426a800098SYoshinobu Inoue (a)^=((t)<<(n))) 3436a800098SYoshinobu Inoue 3446a800098SYoshinobu Inoue #define IP(l,r) \ 3456a800098SYoshinobu Inoue { \ 3466a800098SYoshinobu Inoue register DES_LONG tt; \ 3476a800098SYoshinobu Inoue PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ 3486a800098SYoshinobu Inoue PERM_OP(l,r,tt,16,0x0000ffffL); \ 3496a800098SYoshinobu Inoue PERM_OP(r,l,tt, 2,0x33333333L); \ 3506a800098SYoshinobu Inoue PERM_OP(l,r,tt, 8,0x00ff00ffL); \ 3516a800098SYoshinobu Inoue PERM_OP(r,l,tt, 1,0x55555555L); \ 3526a800098SYoshinobu Inoue } 3536a800098SYoshinobu Inoue 3546a800098SYoshinobu Inoue #define FP(l,r) \ 3556a800098SYoshinobu Inoue { \ 3566a800098SYoshinobu Inoue register DES_LONG tt; \ 3576a800098SYoshinobu Inoue PERM_OP(l,r,tt, 1,0x55555555L); \ 3586a800098SYoshinobu Inoue PERM_OP(r,l,tt, 8,0x00ff00ffL); \ 3596a800098SYoshinobu Inoue PERM_OP(l,r,tt, 2,0x33333333L); \ 3606a800098SYoshinobu Inoue PERM_OP(r,l,tt,16,0x0000ffffL); \ 3616a800098SYoshinobu Inoue PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ 3626a800098SYoshinobu Inoue } 3636a800098SYoshinobu Inoue #endif 364