home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / descore / part01 next >
Internet Message Format  |  1992-05-23  |  63KB

  1. From: how@isl.stanford.edu (Dana How)
  2. Newsgroups: comp.sources.misc
  3. Subject: v29i128: descore - high performance DES core routines, Part01/01
  4. Message-ID: <1992May21.133430.13381@aber.ac.uk>
  5. Date: 21 May 92 13:34:30 GMT
  6. Approved: aem@aber.ac.uk
  7. X-Md4-Signature: a6861837e10c1a43b8778266ae5bc9b7
  8.  
  9. Submitted-by: how@isl.stanford.edu (Dana How)
  10. Posting-number: Volume 29, Issue 128
  11. Archive-name: descore/part01
  12. Environment: 32BIT
  13. Supersedes: descore: Volume 29, Issue 80
  14.  
  15. this is an update to desCore, a package containing just the core DES
  16. functionality: specifying keys, encryption and decryption.
  17. it remains the most efficient DES code posted, with the following 
  18. encryption/decryption performance on a sparcstation 1:
  19.     variant            blocks/sec    bytes/sec    bits/sec
  20.     with  2k tables        20,000+        160,000+    1,280,000+
  21.     with 64k tables        30,000+        480,000+    3,840,000+
  22. (not quite the 1Gb/sec reported for a GaAs chip at CICC '92 in Boston!)
  23. omitting the initial and final permutation improves the performance even
  24. more;  all four combinations of table size and IP/FP support are provided.
  25.  
  26. i have included a number of changes to increase performance on machines
  27. with fewer registers and less cache than a sparc.  on a sparc there is no
  28. change in performance since the code was already expressed in a minimum number
  29. of RISC operations :-).  i have also shown how the code can take advantage of
  30. CISC bitfield instructions and other CISC quirks.  and with this release,  you
  31. can perform DES on a 386 entirely in the registers if you use gcc.
  32.  
  33. desCore is for those who want to implement such things as DES filters,
  34. rather than UNIX password crackers. for this reason i have not spent much
  35. effort yet to improve the performance of the key-setting routine.
  36.  
  37. i have attempted to keep the package small, portable and easily plugged-in
  38. to kerberos-compatible code. i have NOT reimplemented all the other routines
  39. in kerberos because i have nothing new to add -- that has already been done
  40. at least three times by other people.
  41.  
  42. enjoy!                        posted by how@isl.stanford.edu
  43.  
  44. -----------------------------  CUT HERE -------------------------------
  45. #! /bin/sh
  46. # This is a shell archive.  Remove anything before this line, then unpack
  47. # it by saving it into a file and typing "sh file".  To overwrite existing
  48. # files, type "sh file -c".  You can also feed this as standard input via
  49. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  50. # will see the following message at the end:
  51. #        "End of archive 1 (of 1)."
  52. # Contents:  Makefile README desCode.h desCore.h desKerb.c desQuick.c
  53. #   desTest.c desUtil.c desdata.c desinfo.h
  54. # Wrapped by how@tau on Tue May 19 17:26:40 1992
  55. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  56. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  57.   echo shar: Will not clobber existing file \"'Makefile'\"
  58. else
  59. echo shar: Extracting \"'Makefile'\" \(3970 characters\)
  60. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  61. X#
  62. X#    des - fast & portable DES encryption & decryption.
  63. X#    Copyright (C) 1992  Dana L. How
  64. X#    Please see the file `README' for the complete copyright notice.
  65. X#
  66. X
  67. X# $Id: Makefile,v 1.17 1992/05/19 23:59:13 how E $
  68. X
  69. XCFLAGS=        -g        # debug
  70. XCFLAGS=        -O4        # max opt
  71. XCFLAGS=        -O2
  72. XCPPFLAGS=    -Dsparc        # use 6+8 general regs
  73. XCPPFLAGS=    -Dmc68000    # use 3+3 addr (1+3 live), and 3+3 data regs
  74. XCPPFLAGS=    -Dvax        # use 6+0 general regs
  75. XCPPFLAGS=    -Di386        # use 3+0 regs, and 3+0 normal variables
  76. XCPPFLAGS=    -Dsparc
  77. XLDFLAGS=
  78. XCC=        gcc
  79. XCPP=        $(CC) -E $(CPPFLAGS)
  80. XCODEGEN.c=    $(CC) $(CFLAGS) $(CPPFLAGS) -S
  81. XCOMPILE.c=    $(CC) $(CFLAGS) $(CPPFLAGS) -c
  82. XLINK.c=        $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
  83. X
  84. X# hand-entered files that go into the library
  85. XSC=        desKerb.c desUtil.c desQuick.c
  86. XSO=        desKerb.o desUtil.o desQuick.o
  87. X
  88. X# special generated files
  89. XGH=        parity.h rotors.h keymap.h
  90. XGC=        desSmallFips.c desSmallCore.c desQuickFips.c desQuickCore.c
  91. XGI=        desSmallFips.i desSmallCore.i desQuickFips.i desQuickCore.i
  92. XGO=        desSmallFips.o desSmallCore.o desQuickFips.o desQuickCore.o
  93. X
  94. X# what to distribute
  95. XRCS=        Makefile README                        \
  96. X        desCore.h desinfo.h desCode.h                \
  97. X        desTest.c $(SC) desdata.c
  98. XFILES=        $(RCS)
  99. X
  100. XO=        $(SO) $(GO)
  101. X
  102. X# prefer compilation from .i if .i exists
  103. X.SUFFIXES:
  104. X.SUFFIXES:    .i .o .c $(SUFFIXES)
  105. X
  106. X.PRECIOUS:    $(RCS) test
  107. X
  108. Xtest:        desCore.a desTest.o
  109. X        $(LINK.c) -o $@ desTest.o desCore.a
  110. X        ./test
  111. X
  112. X# get stuff from RCS
  113. X$(RCS):
  114. X        co $@
  115. X
  116. X# test all performance enhancement flags
  117. Xsure:
  118. X        rm *.i; make 'CPPFLAGS=-Dvax     -Umc68000 -Usparc'
  119. X        rm *.i; make 'CPPFLAGS=-Dmc68000 -Usparc'
  120. X        rm *.i; make 'CPPFLAGS=-Dsparc   -Umc68000'
  121. X#was #1        rm *.i; make 'CPPFLAGS=-Di386    -Umc68000 -Usparc'
  122. X
  123. XdesCore.a:    $O
  124. X        ar cru $@ $O
  125. X        ranlib $@
  126. X
  127. Xdesdata.o:    desinfo.h desCore.h
  128. XdesUtil.o:    $(GH)
  129. X$(SO):        desCore.h
  130. X$(GI):        desCode.h desCore.h Makefile
  131. XdesTest.o:    desCore.h
  132. X
  133. X$(GH):        desdata
  134. X        ./desdata $@ > $@
  135. X
  136. Xdesdata:    desdata.o
  137. X        $(LINK.c) -o $@ desdata.o
  138. X
  139. Xtar:        $(FILES)
  140. X        tar cf des.tar $(FILES)
  141. X
  142. Xshar:        $(FILES)
  143. X        makekit -ndes.shar -s58k '-tnow run make' $(FILES)
  144. X
  145. Xlint:        desTest.c $(SC) $(GC)
  146. X        lint    $(CPPFLAGS) \
  147. X            desTest.c $(SC) $(GC) | \
  148. X        sed    '/possible pointer alignment problem/d'
  149. X
  150. Xwarn:        desTest.c $(SC) $(GC)
  151. X        gcc    -Wall -ansi -pedantic $(CPPFLAGS) -O2 \
  152. X            desTest.c $(SC) $(GC)
  153. X
  154. X# new rules  (note: tr|sed|tr is NOT necessary,  just there so .i is readable)
  155. X.c.i:
  156. X    $(CPP) $< > $*.x
  157. X    @tr ';'\\012 \\012';' < $*.x |            \
  158. X     sed    -e 's/[     ][     ]*/ /g'        \
  159. X        -e 's/^ //'                \
  160. X        -e 's/ $$//'                \
  161. X        -e '/^$$/d'                \
  162. X        -e '/^[^;]/s/^/;/'            \
  163. X        -e 's/#[^;]*;//g'            \
  164. X        -e 's/\([){]\) *\(register\)/\1;\2/g'    \
  165. X        -e 's/do {/do {;/g'            \
  166. X        -e 's/\([[(]\) /\1/g'            \
  167. X        -e 's/ \([]),]\)/\1/g'            \
  168. X        -e 's/\([^]+0123 ]\) =/\1  =/g'        \
  169. X        -e 's/} while/@ while/g'        \
  170. X        -e 's/}/};;/g'                \
  171. X        -e 's/@ while/} while/g'        \
  172. X        -e 's/ *; */;/g'            \
  173. X        -e 's/;;;*/;;/g'            \
  174. X        -e '1s/^;*//' |                \
  175. X     tr ';'\\012 \\012';' > $@
  176. X    @echo ""  >> $@
  177. X    @echo "}" >> $@            # last definition must be a procedure
  178. X
  179. X#        -e 's/\(;[kmxyz][0-9]*\)\([^;]*=\)/\1  \2/g'
  180. X
  181. X.i.o:
  182. X        $(CODEGEN.c) $<
  183. X        $(COMPILE.c) $*.s
  184. X
  185. X# slowest to quickest
  186. XdesSmallFips.c:
  187. X        @echo '#include "desCode.h"' > $@
  188. X        @echo \
  189. X'ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
  190. X        @echo \
  191. X'DECRYPT(DesSmallFipsDecrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
  192. XdesSmallCore.c:
  193. X        @echo '#include "desCode.h"' > $@
  194. X        @echo \
  195. X'ENCRYPT(DesSmallCoreEncrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
  196. X        @echo \
  197. X'DECRYPT(DesSmallCoreDecrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
  198. XdesQuickFips.c:
  199. X        @echo '#include "desCode.h"' > $@
  200. X        @echo \
  201. X'ENCRYPT(DesQuickFipsEncrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
  202. X        @echo \
  203. X'DECRYPT(DesQuickFipsDecrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
  204. XdesQuickCore.c:
  205. X        @echo '#include "desCode.h"' > $@
  206. X        @echo \
  207. X'ENCRYPT(DesQuickCoreEncrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
  208. X        @echo \
  209. X'DECRYPT(DesQuickCoreDecrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
  210. END_OF_FILE
  211. if test 3970 -ne `wc -c <'Makefile'`; then
  212.     echo shar: \"'Makefile'\" unpacked with wrong size!
  213. fi
  214. # end of 'Makefile'
  215. fi
  216. if test -f 'README' -a "${1}" != "-c" ; then 
  217.   echo shar: Will not clobber existing file \"'README'\"
  218. else
  219. echo shar: Extracting \"'README'\" \(17055 characters\)
  220. sed "s/^X//" >'README' <<'END_OF_FILE'
  221. Xdes - fast & portable DES encryption & decryption.
  222. XCopyright (C) 1992  Dana L. How
  223. X
  224. XThis program is free software; you can redistribute it and/or modify
  225. Xit under the terms of the GNU Library General Public License as published by
  226. Xthe Free Software Foundation; either version 2 of the License, or
  227. X(at your option) any later version.
  228. X
  229. XThis program is distributed in the hope that it will be useful,
  230. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  231. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  232. XGNU Library General Public License for more details.
  233. X
  234. XYou should have received a copy of the GNU Library General Public License
  235. Xalong with this program; if not, write to the Free Software
  236. XFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  237. X
  238. XAuthor's address: how@isl.stanford.edu
  239. X
  240. X$Id: README,v 1.15 1992/05/20 00:25:32 how E $
  241. X
  242. X
  243. X==>> To compile after untarring/unsharring, just `make' <<==
  244. X
  245. X
  246. XThis package was designed with the following goals:
  247. X1.    Highest possible encryption/decryption PERFORMANCE.
  248. X2.    PORTABILITY to any byte-addressable host with a 32bit unsigned C type
  249. X3.    Plug-compatible replacement for KERBEROS's low-level routines.
  250. X
  251. XThis second release includes a number of performance enhancements for
  252. Xregister-starved machines.  My discussions with Richard Outerbridge,
  253. X71755.204@compuserve.com, sparked a number of these enhancements.
  254. X
  255. XTo more rapidly understand the code in this package, inspect desSmallFips.i
  256. X(created by typing `make') BEFORE you tackle desCode.h.  The latter is set
  257. Xup in a parameterized fashion so it can easily be modified by speed-daemon
  258. Xhackers in pursuit of that last microsecond.  You will find it more
  259. Xilluminating to inspect one specific implementation,
  260. Xand then move on to the common abstract skeleton with this one in mind.
  261. X
  262. X
  263. Xperformance comparison to other available des code which i could
  264. Xcompile on a SPARCStation 1 (cc -O4, gcc -O2):
  265. X
  266. Xthis code (byte-order independent):
  267. X   30us per encryption (options: 64k tables, no IP/FP)
  268. X   33us per encryption (options: 64k tables, FIPS standard bit ordering)
  269. X   45us per encryption (options:  2k tables, no IP/FP)
  270. X   48us per encryption (options:  2k tables, FIPS standard bit ordering)
  271. X  275us to set a new key (uses 1k of key tables)
  272. X    this has the quickest encryption/decryption routines i've seen.
  273. X    since i was interested in fast des filters rather than crypt(3)
  274. X    and password cracking, i haven't really bothered yet to speed up
  275. X    the key setting routine. also, i have no interest in re-implementing
  276. X    all the other junk in the mit kerberos des library, so i've just
  277. X    provided my routines with little stub interfaces so they can be
  278. X    used as drop-in replacements with mit's code or any of the mit-
  279. X    compatible packages below. (note that the first two timings above
  280. X    are highly variable because of cache effects).
  281. X
  282. Xkerberos des replacement from australia (version 1.95):
  283. X   53us per encryption (uses 2k of tables)
  284. X   96us to set a new key (uses 2.25k of key tables)
  285. X    so despite the author's inclusion of some of the performance
  286. X    improvements i had suggested to him, this package's
  287. X    encryption/decryption is still slower on the sparc and 68000.
  288. X    more specifically, 19-40% slower on the 68020 and 11-35% slower
  289. X    on the sparc,  depending on the compiler;
  290. X    in full gory detail (ALT_ECB is a libdes variant):
  291. X    compiler       machine        desCore    libdes    ALT_ECB    slower by
  292. X    gcc 2.1 -O2    Sun 3/110    304  uS    369.5uS    461.8uS     22%
  293. X    cc      -O1    Sun 3/110    336  uS    436.6uS    399.3uS     19%
  294. X    cc      -O2    Sun 3/110    360  uS    532.4uS    505.1uS     40%
  295. X    cc      -O4    Sun 3/110    365  uS    532.3uS    505.3uS     38%
  296. X    gcc 2.1 -O2    Sun 4/50     48  uS     53.4uS     57.5uS     11%
  297. X    cc      -O2    Sun 4/50     48  uS     64.6uS     64.7uS     35%
  298. X    cc      -O4    Sun 4/50     48  uS     64.7uS     64.9uS     35%
  299. X    (my time measurements are not as accurate as his).
  300. X   the comments in my first release of desCore on version 1.92:
  301. X   68us per encryption (uses 2k of tables)
  302. X   96us to set a new key (uses 2.25k of key tables)
  303. X    this is a very nice package which implements the most important
  304. X    of the optimizations which i did in my encryption routines.
  305. X    it's a bit weak on common low-level optimizations which is why
  306. X    it's 39%-106% slower.  because he was interested in fast crypt(3) and
  307. X    password-cracking applications,  he also used the same ideas to
  308. X    speed up the key-setting routines with impressive results.
  309. X    (at some point i may do the same in my package).  he also implements
  310. X    the rest of the mit des library.
  311. X    (code from eay@psych.psy.uq.oz.au via comp.sources.misc)
  312. X
  313. Xfast crypt(3) package from denmark:
  314. X    the des routine here is buried inside a loop to do the
  315. X    crypt function and i didn't feel like ripping it out and measuring
  316. X    performance. his code takes 26 sparc instructions to compute one
  317. X    des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
  318. X    he claims to use 280k of tables but the iteration calculation seems
  319. X    to use only 128k.  his tables and code are machine independent.
  320. X    (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
  321. X
  322. Xswedish reimplementation of Kerberos des library
  323. X  108us per encryption (uses 34k worth of tables)
  324. X  134us to set a new key (uses 32k of key tables to get this speed!)
  325. X    the tables used seem to be machine-independent;
  326. X    he seems to have included a lot of special case code
  327. X    so that, e.g., `long' loads can be used instead of 4 `char' loads
  328. X    when the machine's architecture allows it.
  329. X    (code obtained from chalmers.se:pub/des)
  330. X
  331. Xcrack 3.3c package from england:
  332. X    as in crypt above, the des routine is buried in a loop. it's
  333. X    also very modified for crypt.  his iteration code uses 16k
  334. X    of tables and appears to be slow.
  335. X    (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
  336. X
  337. X``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
  338. X  165us per encryption (uses 6k worth of tables)
  339. X  478us to set a new key (uses <1k of key tables)
  340. X    so despite the comments in this code, it was possible to get
  341. X    faster code AND smaller tables, as well as making the tables
  342. X    machine-independent.
  343. X    (code obtained from prep.ai.mit.edu)
  344. X
  345. XUC Berkeley code (depends on machine-endedness):
  346. X  226us per encryption
  347. X10848us to set a new key
  348. X    table sizes are unclear, but they don't look very small
  349. X    (code obtained from wuarchive.wustl.edu)
  350. X
  351. X
  352. Xmotivation and history
  353. X
  354. Xa while ago i wanted some des routines and the routines documented on sun's
  355. Xman pages either didn't exist or dumped core.  i had heard of kerberos,
  356. Xand knew that it used des,  so i figured i'd use its routines.  but once
  357. Xi got it and looked at the code,  it really set off a lot of pet peeves -
  358. Xit was too convoluted, the code had been written without taking
  359. Xadvantage of the regular structure of operations such as IP, E, and FP
  360. X(i.e. the author didn't sit down and think before coding),
  361. Xit was excessively slow,  the author had attempted to clarify the code
  362. Xby adding MORE statements to make the data movement more `consistent'
  363. Xinstead of simplifying his implementation and cutting down on all data
  364. Xmovement (in particular, his use of L1, R1, L2, R2), and it was full of
  365. Xidiotic `tweaks' for particular machines which failed to deliver significant
  366. Xspeedups but which did obfuscate everything.  so i took the test data
  367. Xfrom his verification program and rewrote everything else.
  368. X
  369. Xa while later i ran across the great crypt(3) package mentioned above.
  370. Xthe fact that this guy was computing 2 sboxes per table lookup rather
  371. Xthan one (and using a MUCH larger table in the process) emboldened me to
  372. Xdo the same - it was a trivial change from which i had been scared away
  373. Xby the larger table size.  in his case he didn't realize you don't need to keep
  374. Xthe working data in TWO forms, one for easy use of half the sboxes in
  375. Xindexing, the other for easy use of the other half; instead you can keep
  376. Xit in the form for the first half and use a simple rotate to get the other
  377. Xhalf.  this means i have (almost) half the data manipulation and half
  378. Xthe table size.  in fairness though he might be encoding something particular
  379. Xto crypt(3) in his tables - i didn't check.
  380. X
  381. Xi'm glad that i implemented it the way i did, because this C version is
  382. Xportable (the ifdef's are performance enhancements) and it is faster
  383. Xthan versions hand-written in assembly for the sparc!
  384. X
  385. X
  386. Xporting notes
  387. X
  388. Xone thing i did not want to do was write an enormous mess
  389. Xwhich depended on endedness and other machine quirks,
  390. Xand which necessarily produced different code and different lookup tables
  391. Xfor different machines.  see the kerberos code for an example
  392. Xof what i didn't want to do; all their endedness-specific `optimizations'
  393. Xobfuscate the code and in the end were slower than a simpler machine
  394. Xindependent approach.  however, there are always some portability
  395. Xconsiderations of some kind, and i have included some options
  396. Xfor varying numbers of register variables.
  397. Xperhaps some will still regard the result as a mess!
  398. X
  399. X1) i assume everything is byte addressable, although i don't actually
  400. X   depend on the byte order, and that bytes are 8 bits.
  401. X   i assume word pointers can be freely cast to and from char pointers.
  402. X   note that 99% of C programs make these assumptions.
  403. X   i always use unsigned char's if the high bit could be set.
  404. X2) the typedef `word' means a 32 bit unsigned integral type.
  405. X   if `unsigned long' is not 32 bits, change the typedef in desCore.h.
  406. X   i assume sizeof(word) == 4 EVERYWHERE.
  407. X
  408. Xthe (worst-case) cost of my NOT doing endedness-specific optimizations
  409. Xin the data loading and storing code surrounding the key iterations
  410. Xis less than 12%.  also, there is the added benefit that
  411. Xthe input and output work areas do not need to be word-aligned.
  412. X
  413. X
  414. XOPTIONAL performance optimizations
  415. X
  416. X1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
  417. X   whichever one is closest to the capabilities of your machine.
  418. X   see the start of desCode.h to see exactly what this selection implies.
  419. X   note that if you select the wrong one, the des code will still work;
  420. X   these are just performance tweaks.
  421. X2) for those with functional `asm' keywords: you should change the
  422. X   ROR and ROL macros to use machine rotate instructions if you have them.
  423. X   this will save 2 instructions and a temporary per use,
  424. X   or about 32 to 40 instructions per en/decryption.
  425. X   note that gcc is smart enough to translate the ROL/R macros into
  426. X   machine rotates!
  427. X
  428. Xthese optimizations are all rather persnickety, yet with them you should
  429. Xbe able to get performance equal to assembly-coding, except that:
  430. X1) with the lack of a bit rotate operator in C, rotates have to be synthesized
  431. X   from shifts.  so access to `asm' will speed things up if your machine
  432. X   has rotates, as explained above in (3) (not necessary if you use gcc).
  433. X2) if your machine has less than 12 32-bit registers i doubt your compiler will
  434. X   generate good code.
  435. X   `i386' tries to configure the code for a 386 by only declaring 3 registers
  436. X   (it appears that gcc can use ebx, esi and edi to hold register variables).
  437. X   however, if you like assembly coding, the 386 does have 7 32-bit registers,
  438. X   and if you use ALL of them, use `scaled by 8' address modes with displacement
  439. X   and other tricks, you can get reasonable routines for DesQuickCore... with
  440. X   about 250 instructions apiece.  For DesSmall... it will help to rearrange
  441. X   des_keymap, i.e., now the sbox # is the high part of the index and
  442. X   the 6 bits of data is the low part; it helps to exchange these.
  443. X   since i have no way to conveniently test it i have not provided my
  444. X   shoehorned 386 version.  note that with this release of desCore, gcc is able
  445. X   to put everything in registers(!), and generate about 370 instructions apiece
  446. X   for the DesQuickCore... routines!
  447. X
  448. Xcoding notes
  449. X
  450. Xthe en/decryption routines each use 6 necessary register variables,
  451. Xwith 4 being actively used at once during the inner iterations.
  452. Xif you don't have 4 register variables get a new machine.
  453. Xup to 8 more registers are used to hold constants in some configurations.
  454. X
  455. Xi assume that the use of a constant is more expensive than using a register:
  456. Xa) additionally, i have tried to put the larger constants in registers.
  457. X   registering priority was by the following:
  458. X    anything more than 12 bits (bad for RISC and CISC)
  459. X    greater than 127 in value (can't use movq or byte immediate on CISC)
  460. X    9-127 (may not be able to use CISC shift immediate or add/sub quick),
  461. X    1-8 were never registered, being the cheapest constants.
  462. Xb) the compiler may be too stupid to realize table and table+256 should
  463. X   be assigned to different constant registers and instead repetitively
  464. X   do the arithmetic, so i assign these to explicit `m' register variables
  465. X   when possible and helpful.
  466. X
  467. Xi assume that indexing is cheaper or equivalent to auto increment/decrement,
  468. Xwhere the index is 7 bits unsigned or smaller.
  469. Xthis assumption is reversed for 68k and vax.
  470. X
  471. Xi assume that addresses can be cheaply formed from two registers,
  472. Xor from a register and a small constant.
  473. Xfor the 68000, the `two registers and small offset' form is used sparingly.
  474. Xall index scaling is done explicitly - no hidden shifts by log2(sizeof).
  475. X
  476. Xthe code is written so that even a dumb compiler
  477. Xshould never need more than one hidden temporary,
  478. Xincreasing the chance that everything will fit in the registers.
  479. XKEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
  480. X(actually, there are some code fragments now which do require two temps,
  481. Xbut fixing it would either break the structure of the macros or
  482. Xrequire declaring another temporary).
  483. X
  484. X
  485. Xspecial efficient data format
  486. X
  487. Xbits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
  488. X    003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
  489. X(the x bits are still there, i'm just emphasizing where the S boxes are).
  490. Xbits are rotated left 4 when computing S6 S4 S2 S0:
  491. X    282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
  492. Xthe rightmost two bits are usually cleared so the lower byte can be used
  493. Xas an index into an sbox mapping table. the next two x'd bits are set
  494. Xto various values to access different parts of the tables.
  495. X
  496. X
  497. Xhow to use the routines
  498. X
  499. Xdatatypes:
  500. X    pointer to 8 byte area of type DesData
  501. X    used to hold keys and input/output blocks to des.
  502. X
  503. X    pointer to 128 byte area of type DesKeys
  504. X    used to hold full 768-bit key.
  505. X    must be long-aligned.
  506. X
  507. XDesQuickInit()
  508. X    call this before using any other routine with `Quick' in its name.
  509. X    it generates the special 64k table these routines need.
  510. XDesQuickDone()
  511. X    frees this table
  512. X
  513. XDesMethod(m, k)
  514. X    m points to a 128byte block, k points to an 8 byte des key
  515. X    which must have odd parity (or -1 is returned) and which must
  516. X    not be a (semi-)weak key (or -2 is returned).
  517. X    normally DesMethod() returns 0.
  518. X    m is filled in from k so that when one of the routines below
  519. X    is called with m, the routine will act like standard des
  520. X    en/decryption with the key k. if you use DesMethod,
  521. X    you supply a standard 56bit key; however, if you fill in
  522. X    m yourself, you will get a 768bit key - but then it won't
  523. X    be standard.  it's 768bits not 1024 because the least significant
  524. X    two bits of each byte are not used.  note that these two bits
  525. X    will be set to magic constants which speed up the encryption/decryption
  526. X    on some machines.  and yes, each byte controls
  527. X    a specific sbox during a specific iteration.
  528. X    you really shouldn't use the 768bit format directly;  i should
  529. X    provide a routine that converts 128 6-bit bytes (specified in
  530. X    S-box mapping order or something) into the right format for you.
  531. X    this would entail some byte concatenation and rotation.
  532. X
  533. XDes{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
  534. X    performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
  535. X    uses m as a 768bit key as explained above.
  536. X    the Encrypt|Decrypt choice is obvious.
  537. X    Fips|Core determines whether a completely standard FIPS initial
  538. X    and final permutation is done; if not, then the data is loaded
  539. X    and stored in a nonstandard bit order (FIPS w/o IP/FP).
  540. X    Fips slows down Quick by 10%, Small by 9%.
  541. X    Small|Quick determines whether you use the normal routine
  542. X    or the crazy quick one which gobbles up 64k more of memory.
  543. X    Small is 50% slower then Quick, but Quick needs 32 times as much
  544. X    memory.  Quick is included for programs that do nothing but DES,
  545. X    e.g., encryption filters, etc.
  546. X
  547. X
  548. XGetting it to compile on your machine
  549. X
  550. Xthere are no machine-dependencies in the code (see porting),
  551. Xexcept perhaps the `now()' macro in desTest.c.
  552. XALL generated tables are machine independent.
  553. Xyou should edit the Makefile with the appropriate optimization flags
  554. Xfor your compiler (MAX optimization).
  555. X
  556. X
  557. XSpeeding up kerberos (and/or its des library)
  558. X
  559. Xnote that i have included a kerberos-compatible interface in desUtil.c
  560. Xthrough the functions des_key_sched() and des_ecb_encrypt().
  561. Xto use these with kerberos or kerberos-compatible code put desCore.a
  562. Xahead of the kerberos-compatible library on your linker's command line.
  563. Xyou should not need to #include desCore.h;  just include the header
  564. Xfile provided with the kerberos library.
  565. X
  566. XOther uses
  567. X
  568. Xthe macros in desCode.h would be very useful for putting inline des
  569. Xfunctions in more complicated encryption routines.
  570. END_OF_FILE
  571. if test 17055 -ne `wc -c <'README'`; then
  572.     echo shar: \"'README'\" unpacked with wrong size!
  573. fi
  574. # end of 'README'
  575. fi
  576. if test -f 'desCode.h' -a "${1}" != "-c" ; then 
  577.   echo shar: Will not clobber existing file \"'desCode.h'\"
  578. else
  579. echo shar: Extracting \"'desCode.h'\" \(14436 characters\)
  580. sed "s/^X//" >'desCode.h' <<'END_OF_FILE'
  581. X/*
  582. X *    des - fast & portable DES encryption & decryption.
  583. X *    Copyright (C) 1992  Dana L. How
  584. X *    Please see the file `README' for the complete copyright notice.
  585. X */
  586. X
  587. X#ifndef    lint
  588. Xstatic char desCode_hRcs[] = "$Id: desCode.h,v 1.21 1992/05/20 00:00:57 how E $";
  589. X#endif
  590. X
  591. X#include    "desCore.h"
  592. Xextern word des_keymap[], des_bigmap[];
  593. X
  594. X
  595. X/* optional customization:
  596. X * the idea here is to alter the code so it will still run correctly
  597. X * on any machine,  but the quickest on the specific machine in mind.
  598. X * note that these silly tweaks can give you a 15%-20% speed improvement
  599. X * on the sparc -- it's probably even more significant on the 68000. */
  600. X
  601. X/* take care of machines with incredibly few registers */
  602. X#if    defined(i386)
  603. X#define    REGISTER        /* only x, y, z will be declared register */
  604. X#else
  605. X#define    REGISTER    register
  606. X#endif    /* i386 */
  607. X
  608. X/* is auto inc/dec faster than 7bit unsigned indexing? */
  609. X#if    defined(vax) || defined(mc68000)
  610. X#define    FIXR        r += 32;
  611. X#define    FIXS        s +=  8;
  612. X#define    PREV(v,o)    *--v
  613. X#define    NEXT(v,o)    *v++
  614. X#define    BUMP(v,n)
  615. X#else
  616. X#define    FIXR
  617. X#define    FIXS
  618. X#define    PREV(v,o)    v[o]
  619. X#define    NEXT(v,o)    v[o]
  620. X#define    BUMP(v,n)    v += n;
  621. X#endif
  622. X
  623. X/* if no machine type, default is indexing, 6 registers and cheap literals */
  624. X#if    !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
  625. X#define    vax
  626. X#endif
  627. X
  628. X/* handle a compiler which can't reallocate registers */
  629. X#if    defined(strange)            /* didn't feel like deleting */
  630. X#define    SREGFREE    ; s = D
  631. X#define    DEST        s
  632. X#define    D        m0
  633. X#else
  634. X#define    SREGFREE
  635. X#define    DEST        d
  636. X#define    D        d
  637. X#endif
  638. X
  639. X/* explanation of configuration macros:
  640. X *    REG.....    declares any extra registers needed.
  641. X *    SET.....    sets those registers which should hold constants.
  642. X *    .F        fiddle with word before xor'ing with key schedule.
  643. X *    .Ln        do table lookup number n.
  644. X *    .An        accumulate table lookups starting at n.
  645. X * where the dots are replaced by one of Q(UICK) or S(MALL).
  646. X */
  647. X
  648. X/* handle constants in the optimal way for vax */
  649. X/* we use 6 variables, all declared register;
  650. X * we assume address literals are cheap & unrestricted;
  651. X * we assume immediate constants are cheap & unrestricted.
  652. X *
  653. X * note that the low 2 bits in each bit mask can be turned off,
  654. X * permitting the removal of the pesky -2 and -3 offsets and subsequent
  655. X * identification of the address literals as CSEs.  however, we did _assume_
  656. X * that address literals were cheap, and this would prevent the translation
  657. X * of (value >> bits) & mask into a single CISC bitfield instruction. */
  658. X#if    defined(vax)
  659. X#define    REGQUICK
  660. X#define    SETQUICK
  661. X#define    QF(zs)        (zs & 0XFCFCFCFCL)
  662. X#define    QL0(z)        ADD((byte *)des_bigmap            , z       &  0XFFFF)
  663. X#define    QL1(z)        ADD((byte *)des_bigmap         - 2, z >> 16          )
  664. X#define    QL2(z)        ADD((byte *)des_bigmap - 0x100    , z       &  0XFFFF)
  665. X#define    QL3(z)        ADD((byte *)des_bigmap - 0x100 - 2, z >> 16          )
  666. X#define    QA0(x,A,B)    x ^= A; x ^= B
  667. X#define    QA2(x,A,B)    x ^= A; x ^= B
  668. X#define    REGSMALL
  669. X#define    SETSMALL
  670. X#define    SF(zs)        (zs & 0XFCFCFCFCL)
  671. X#define    SL0(z)        ADD((byte *)des_keymap         - 0,  z        & 0X3FF)
  672. X#define    SL1(z)        ADD((byte *)des_keymap         - 3, (z >>  8) & 0X3FF)
  673. X#define    SL2(z)        ADD((byte *)des_keymap         - 2, (z >> 16) & 0X3FF)
  674. X#define    SL3(z)        ADD((byte *)des_keymap         - 1,  z >> 24         )
  675. X#define    SL4(z)        ADD((byte *)des_keymap + 0x400 - 0,  z        & 0X3FF)
  676. X#define    SL5(z)        ADD((byte *)des_keymap + 0x400 - 3, (z >>  8) & 0X3FF)
  677. X#define    SL6(z)        ADD((byte *)des_keymap + 0x400 - 2, (z >> 16) & 0X3FF)
  678. X#define    SL7(z)        ADD((byte *)des_keymap + 0x400 - 1,  z >> 24         )
  679. X#define    SA0(x,A,B,C,D)    x ^= A; x ^= B; x ^= C; x ^= D
  680. X#define    SA4(x,A,B,C,D)    x ^= A; x ^= B; x ^= C; x ^= D
  681. X#define    UNROLL        1
  682. X#endif    /* defined(vax) */
  683. X
  684. X/* handle constants in the optimal way for 386 */
  685. X/* we declare 3 register variables (see above) and use 3 more variables;
  686. X * we assume address literals are cheap & unrestricted;
  687. X * we assume immediate constants are cheap & unrestricted.
  688. X * so that movzx is used we do NOT turn off the low 2 bits in each bit mask. */
  689. X#if    defined(i386)
  690. X#define    REGQUICK
  691. X#define    SETQUICK
  692. X#define    QF(zs)        (zs & 0XFCFCFCFCL)
  693. X#define    QL0(z)        ADD((byte *)des_bigmap            , z       &  0XFFFF)
  694. X#define    QL1(z)        ADD((byte *)des_bigmap         - 2, z >> 16          )
  695. X#define    QL2(z)        ADD((byte *)des_bigmap - 0x100    , z       &  0XFFFF)
  696. X#define    QL3(z)        ADD((byte *)des_bigmap - 0x100 - 2, z >> 16          )
  697. X#define    QA0(x,A,B)    x ^= A; x ^= B
  698. X#define    QA2(x,A,B)    x ^= A; x ^= B
  699. X#define    REGSMALL
  700. X#define    SETSMALL
  701. X#define    SF(zs)        (zs & 0XFCFCFCFCL)
  702. X#define    SL0(z)        ADD((byte *)des_keymap + 0x300 - 0,  z        & 0X0FF)
  703. X#define    SL1(z)        ADD((byte *)des_keymap + 0x200 - 3, (z >>= 8) & 0X0FF)
  704. X#define    SL2(z)        ADD((byte *)des_keymap + 0x100 - 2, (z >>= 8) & 0X0FF)
  705. X#define    SL3(z)        ADD((byte *)des_keymap         - 1,  z >>= 8         )
  706. X#define    SL4(z)        ADD((byte *)des_keymap + 0x700 - 0,  z        & 0X0FF)
  707. X#define    SL5(z)        ADD((byte *)des_keymap + 0x600 - 3, (z >>= 8) & 0X0FF)
  708. X#define    SL6(z)        ADD((byte *)des_keymap + 0x500 - 2, (z >>= 8) & 0X0FF)
  709. X#define    SL7(z)        ADD((byte *)des_keymap + 0x400 - 1,  z >>= 8         )
  710. X#define    SA0(x,A,B,C,D)    x ^= A; x ^= B; x ^= C; x ^= D
  711. X#define    SA4(x,A,B,C,D)    x ^= A; x ^= B; x ^= C; x ^= D
  712. X#define    UNROLL        1
  713. X#endif    /* defined(i386) */
  714. X
  715. X/* handle constants in the optimal way for mc68000 */
  716. X/* in addition to the core 6 variables, we declare 3 registers holding constants
  717. X * and 3 registers holding address literals.  `a' accumulates lookups.
  718. X * at most 6 data values and 4 address values are actively used at once.
  719. X * we assume address literals are so expensive we never use them;
  720. X * we assume constant index offsets > 127 are expensive, so they are not used.
  721. X * we assume all constants are expensive and put them in registers. */
  722. X#if    defined(mc68000)
  723. X#define    REGQUICK                \
  724. X    register word a;            \
  725. X    register word *e;            \
  726. X    register word k0, k1;            \
  727. X    register byte *m0, *m1;
  728. X#define    SETQUICK                \
  729. X    ; k0 = 0XFFFF                \
  730. X    ; k1 = 0XFCFCFCFCL            \
  731. X    ; m0 = (byte *)des_bigmap        \
  732. X    ; m1 = m0 - 0x100
  733. X#define    QF(zs)        (zs & k1)
  734. X#define    QL0(z)        ADD(m0    ,  z        & k0)
  735. X#define    QL1(z)        ADD(m0 - 2,  z >> 16      )
  736. X#define    QL2(z)        ADD(m1    ,  z        & k0)
  737. X#define    QL3(z)        ADD(m1 - 2,  z >> 16      )
  738. X#define    QA0(x,A,B)    a  = A; a += B
  739. X#define    QA2(x,A,B)    a += A; a += B; x ^= a
  740. X#define    REGSMALL                \
  741. X    register word a;            \
  742. X    register word *e;            \
  743. X    register word k0, k1;            \
  744. X    register byte *m0, *m1;
  745. X#define    SETSMALL                \
  746. X    ; k0 = 0X3FC                \
  747. X    ; k1 = 0XFCFCFCFCL            \
  748. X    ; m0 = (byte *)des_keymap        \
  749. X    ; m1 = m0 + 0x400
  750. X#define    SF(zs)        (zs & k1)
  751. X#define    SL0(z)        ADD(m0    ,  z        & k0)
  752. X#define    SL1(z)        ADD(m0    , (z >>= 8) & k0)
  753. X#define    SL2(z)        ADD(m0    , (z >>= 8) & k0)
  754. X#define    SL3(z)        ADD(m0 - 1,  z >>= 8      )
  755. X#define    SL4(z)        ADD(m1    ,  z        & k0)
  756. X#define    SL5(z)        ADD(m1    , (z >>= 8) & k0)
  757. X#define    SL6(z)        ADD(m1    , (z >>= 8) & k0)
  758. X#define    SL7(z)        ADD(m1 - 1,  z >>= 8      )
  759. X#define    SA0(x,A,B,C,D)    a  = A; a += B; a += C; a += D
  760. X#define    SA4(x,A,B,C,D)    a += A; a += B; a += C; a += D; x ^= a
  761. X#define    UNROLL        0
  762. X#endif    /* defined(mc68000) */
  763. X
  764. X/* handle constants in the optimal way for sparc */
  765. X/* in addition to the core 6 variables, we either declare:
  766. X * 4 registers holding address literals and 1 register holding a constant, or
  767. X * 8 registers holding address literals.
  768. X * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
  769. X * we assume address literals are so expensive we never use them;
  770. X * we assume any constant with >10 bits is expensive and put it in a register,
  771. X * and any other is cheap and is coded in-line. */
  772. X#if    defined(sparc)
  773. X#define    REGQUICK                \
  774. X    register word k0;            \
  775. X    register byte *m0, *m1, *m2, *m3;
  776. X#define    SETQUICK                \
  777. X    ; k0 = 0XFCFC                \
  778. X    ; m0 = (byte *)des_bigmap        \
  779. X    ; m1 = m0 + 0x100            \
  780. X    ; m2 = m1 + 0x100            \
  781. X    ; m3 = m2 + 0x100
  782. X#define    QF(zs)        zs
  783. X#define    QL0(z)        ADD(m3,  z        & k0)
  784. X#define    QL1(z)        ADD(m1, (z >> 16) & k0)
  785. X#define    QL2(z)        ADD(m2,  z        & k0)
  786. X#define    QL3(z)        ADD(m0, (z >> 16) & k0)
  787. X#define    QA0(x,A,B)    x ^= A + B
  788. X#define    QA2(x,A,B)    x ^= A + B
  789. X#define    REGSMALL                \
  790. X    register byte *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
  791. X#define    SETSMALL                \
  792. X    ; m0 = (byte *)des_keymap        \
  793. X    ; m1 = m0 + 0x100            \
  794. X    ; m2 = m1 + 0x100            \
  795. X    ; m3 = m2 + 0x100            \
  796. X    ; m4 = m3 + 0x100            \
  797. X    ; m5 = m4 + 0x100            \
  798. X    ; m6 = m5 + 0x100            \
  799. X    ; m7 = m6 + 0x100
  800. X#define    SF(zs)        zs
  801. X#define    SL0(z)        ADD(m3,  z        & 0XFC)
  802. X#define    SL1(z)        ADD(m2, (z >>  8) & 0XFC)
  803. X#define    SL2(z)        ADD(m1, (z >> 16) & 0XFC)
  804. X#define    SL3(z)        ADD(m0, (z >> 24) & 0XFC)
  805. X#define    SL4(z)        ADD(m7,  z        & 0XFC)
  806. X#define    SL5(z)        ADD(m6, (z >>  8) & 0XFC)
  807. X#define    SL6(z)        ADD(m5, (z >> 16) & 0XFC)
  808. X#define    SL7(z)        ADD(m4, (z >> 24) & 0XFC)
  809. X#define    SA0(x,A,B,C,D)    x ^= A + B + C + D
  810. X#define    SA4(x,A,B,C,D)    x ^= A + B + C + D
  811. X#define    UNROLL        1
  812. X#endif    /* defined(sparc) */
  813. X
  814. X
  815. X/* some basic stuff */
  816. X
  817. X/* generate addresses from a base and an index */
  818. X#define    ADD(b,x)    (word *) (b + (x))
  819. X
  820. X/* low level rotate operations */
  821. X#define    NOP(d,s,c,o)
  822. X#define    ROL(d,s,c,o)    d = s << c | s >> o
  823. X#define    ROR(d,s,c,o)    d = s >> c | s << o
  824. X#define    ROL1(d)        ROL(d, d, 1, 31)
  825. X#define    ROR1(d)        ROR(d, d, 1, 31)
  826. X
  827. X/* elementary swap for doing IP/FP */
  828. X#define    SWAP(x,y,m,b)                \
  829. X    z  = ((x >> b) ^ y) & m;        \
  830. X    x ^= z << b;                \
  831. X    y ^= z
  832. X
  833. X
  834. X/* the following macros contain all the important code fragments */
  835. X
  836. X/* load input data, then setup special registers holding constants */
  837. X#define    TEMPQUICK(LOAD)                \
  838. X    REGQUICK                \
  839. X    LOAD()                    \
  840. X    SETQUICK
  841. X#define    TEMPSMALL(LOAD)                \
  842. X    REGSMALL                \
  843. X    LOAD()                    \
  844. X    SETSMALL
  845. X
  846. X/* load data */
  847. X#define    LOADDATA(x,y)                \
  848. X    FIXS                    \
  849. X    y  = PREV(s, 7); y<<= 8;        \
  850. X    y |= PREV(s, 6); y<<= 8;        \
  851. X    y |= PREV(s, 5); y<<= 8;        \
  852. X    y |= PREV(s, 4);            \
  853. X    x  = PREV(s, 3); x<<= 8;        \
  854. X    x |= PREV(s, 2); x<<= 8;        \
  855. X    x |= PREV(s, 1); x<<= 8;        \
  856. X    x |= PREV(s, 0)                \
  857. X    SREGFREE
  858. X/* load data without initial permutation and put into efficient position */
  859. X#define    LOADCORE()                \
  860. X    LOADDATA(x, y);                \
  861. X    ROR1(x);                \
  862. X    ROR1(y)
  863. X/* load data, do the initial permutation and put into efficient position */
  864. X#define    LOADFIPS()                \
  865. X    LOADDATA(y, x);                \
  866. X    SWAP(x, y, 0X0F0F0F0FL, 004);        \
  867. X    SWAP(y, x, 0X0000FFFFL, 020);        \
  868. X    SWAP(x, y, 0X33333333L, 002);        \
  869. X    SWAP(y, x, 0X00FF00FFL, 010);        \
  870. X    ROR1(x);                \
  871. X    z  = (x ^ y) & 0X55555555L;        \
  872. X    y ^= z;                    \
  873. X    x ^= z;                    \
  874. X    ROR1(y)
  875. X
  876. X
  877. X/* core encryption/decryption operations */
  878. X/* S box mapping and P perm with 64k of tables */
  879. X#define    KEYMAPQUICK(x,z,zs,r,m,LOAD,qf,ql0,ql1,qa,sf,sl0,sl1,sl2,sl3,sa) \
  880. X    z  = qf(zs) ^ LOAD(r, m);        \
  881. X    qa(x, *ql0(z), *ql1(z))
  882. X/* small version: use 2k of tables */
  883. X#define    KEYMAPSMALL(x,z,zs,r,m,LOAD,qf,ql0,ql1,qa,sf,sl0,sl1,sl2,sl3,sa) \
  884. X    z  = sf(zs) ^ LOAD(r, m);        \
  885. X    sa(x, *sl0(z), *sl1(z), *sl2(z), *sl3(z))
  886. X/* apply 24 key bits and do the odd  s boxes */
  887. X#define    S7S1(x,y,z,r,m,KEYMAP,LOAD,qa,sa)    \
  888. X    KEYMAP(x,z,y,r,m,LOAD,QF,QL0,QL1,qa,SF,SL0,SL1,SL2,SL3,sa)
  889. X/* apply 24 key bits and do the even s boxes */
  890. X#define    S6S0(x,y,z,r,m,KEYMAP,LOAD,qa,sa)    \
  891. X    ROL(z, y, 4, 28);            \
  892. X    KEYMAP(x,z,z,r,m,LOAD,QF,QL2,QL3,qa,SF,SL4,SL5,SL6,SL7,sa)
  893. X/* an actual iteration.  equivalent except for UPDATE & swapping m and n */
  894. X#define    ENCR(x,y,z,r,m,n,KEYMAP)        \
  895. X    S7S1(x,y,z,r,m,KEYMAP,NEXT,QA0,SA0);    \
  896. X    S6S0(x,y,z,r,n,KEYMAP,NEXT,QA2,SA4)
  897. X#define    DECR(x,y,z,r,m,n,KEYMAP)        \
  898. X    S6S0(x,y,z,r,m,KEYMAP,PREV,QA0,SA0);    \
  899. X    S7S1(x,y,z,r,n,KEYMAP,PREV,QA2,SA4)
  900. X
  901. X/* write out result in correct byte order */
  902. X#define    SAVEDATA(x,y)                \
  903. X    NEXT(DEST, 0) = x; x>>= 8;        \
  904. X    NEXT(DEST, 1) = x; x>>= 8;        \
  905. X    NEXT(DEST, 2) = x; x>>= 8;        \
  906. X    NEXT(DEST, 3) = x;            \
  907. X    NEXT(DEST, 4) = y; y>>= 8;        \
  908. X    NEXT(DEST, 5) = y; y>>= 8;        \
  909. X    NEXT(DEST, 6) = y; y>>= 8;        \
  910. X    NEXT(DEST, 7) = y
  911. X/* write out result */
  912. X#define    SAVECORE()                \
  913. X    ROL1(x);                \
  914. X    ROL1(y);                \
  915. X    SAVEDATA(y, x)
  916. X/* do final permutation and write out result */
  917. X#define    SAVEFIPS()                \
  918. X    ROL1(x);                \
  919. X    z  = (x ^ y) & 0X55555555L;        \
  920. X    y ^= z;                    \
  921. X    x ^= z;                    \
  922. X    ROL1(y);                \
  923. X    SWAP(x, y, 0X00FF00FFL, 010);        \
  924. X    SWAP(y, x, 0X33333333L, 002);        \
  925. X    SWAP(x, y, 0X0000FFFFL, 020);        \
  926. X    SWAP(y, x, 0X0F0F0F0FL, 004);        \
  927. X    SAVEDATA(x, y)
  928. X
  929. X
  930. X/* rolled or unrolled iterations */
  931. X#if    UNROLL
  932. X#define    ENCODE(x,y,z,r,e,KEYMAP)        \
  933. X    ENCR(x,y,z,r, 0, 1,KEYMAP);        \
  934. X    ENCR(y,x,z,r, 2, 3,KEYMAP);        \
  935. X    ENCR(x,y,z,r, 4, 5,KEYMAP);        \
  936. X    ENCR(y,x,z,r, 6, 7,KEYMAP);        \
  937. X    ENCR(x,y,z,r, 8, 9,KEYMAP);        \
  938. X    ENCR(y,x,z,r,10,11,KEYMAP);        \
  939. X    ENCR(x,y,z,r,12,13,KEYMAP);        \
  940. X    ENCR(y,x,z,r,14,15,KEYMAP);        \
  941. X    ENCR(x,y,z,r,16,17,KEYMAP);        \
  942. X    ENCR(y,x,z,r,18,19,KEYMAP);        \
  943. X    ENCR(x,y,z,r,20,21,KEYMAP);        \
  944. X    ENCR(y,x,z,r,22,23,KEYMAP);        \
  945. X    ENCR(x,y,z,r,24,25,KEYMAP);        \
  946. X    ENCR(y,x,z,r,26,27,KEYMAP);        \
  947. X    ENCR(x,y,z,r,28,29,KEYMAP);        \
  948. X    ENCR(y,x,z,r,30,31,KEYMAP)
  949. X#define    DECODE(x,y,z,r,e,KEYMAP)        \
  950. X    FIXR                    \
  951. X    DECR(x,y,z,r,31,30,KEYMAP);        \
  952. X    DECR(y,x,z,r,29,28,KEYMAP);        \
  953. X    DECR(x,y,z,r,27,26,KEYMAP);        \
  954. X    DECR(y,x,z,r,25,24,KEYMAP);        \
  955. X    DECR(x,y,z,r,23,22,KEYMAP);        \
  956. X    DECR(y,x,z,r,21,20,KEYMAP);        \
  957. X    DECR(x,y,z,r,19,18,KEYMAP);        \
  958. X    DECR(y,x,z,r,17,16,KEYMAP);        \
  959. X    DECR(x,y,z,r,15,14,KEYMAP);        \
  960. X    DECR(y,x,z,r,13,12,KEYMAP);        \
  961. X    DECR(x,y,z,r,11,10,KEYMAP);        \
  962. X    DECR(y,x,z,r, 9, 8,KEYMAP);        \
  963. X    DECR(x,y,z,r, 7, 6,KEYMAP);        \
  964. X    DECR(y,x,z,r, 5, 4,KEYMAP);        \
  965. X    DECR(x,y,z,r, 3, 2,KEYMAP);        \
  966. X    DECR(y,x,z,r, 1, 0,KEYMAP)
  967. X#else
  968. X#define    ENCODE(x,y,z,r,e,KEYMAP)        \
  969. X    e = r + 32;                \
  970. X    do {                    \
  971. X        ENCR(x,y,z,r, 0, 1,KEYMAP);    \
  972. X        ENCR(y,x,z,r, 2, 3,KEYMAP);    \
  973. X        BUMP(r,  4)            \
  974. X    } while ( r < e )
  975. X#define    DECODE(x,y,z,r,e,KEYMAP)        \
  976. X    e = r;                    \
  977. X    r += 32;                \
  978. X    do {                    \
  979. X        DECR(x,y,z,r,-1,-2,KEYMAP);    \
  980. X        DECR(y,x,z,r,-3,-4,KEYMAP);    \
  981. X        BUMP(r, -4)            \
  982. X    } while ( r > e )
  983. X#endif
  984. X
  985. X
  986. X/* the following macros contain the encryption/decryption skeletons */
  987. X
  988. X#define    ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE)    \
  989. X                        \
  990. Xvoid                        \
  991. XNAME(D, r, s)                    \
  992. XREGISTER byte * D;                \
  993. XREGISTER word * r;                \
  994. XREGISTER byte * s;                \
  995. X{                        \
  996. X    register word x, y, z;            \
  997. X                        \
  998. X    /* declare temps & load data */        \
  999. X    TEMP(LOAD);                \
  1000. X                        \
  1001. X    /* do the 16 iterations */        \
  1002. X    ENCODE(x,y,z,r,e,KEYMAP);        \
  1003. X                        \
  1004. X    /* save result */            \
  1005. X    SAVE();                    \
  1006. X                        \
  1007. X    return;                    \
  1008. X}
  1009. X
  1010. X#define    DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE)    \
  1011. X                        \
  1012. Xvoid                        \
  1013. XNAME(D, r, s)                    \
  1014. XREGISTER byte * D;                \
  1015. XREGISTER word * r;                \
  1016. XREGISTER byte * s;                \
  1017. X{                        \
  1018. X    register word x, y, z;            \
  1019. X                        \
  1020. X    /* declare temps & load data */        \
  1021. X    TEMP(LOAD);                \
  1022. X                        \
  1023. X    /* do the 16 iterations */        \
  1024. X    DECODE(x,y,z,r,e,KEYMAP);        \
  1025. X                        \
  1026. X    /* save result */            \
  1027. X    SAVE();                    \
  1028. X                        \
  1029. X    return;                    \
  1030. X}
  1031. END_OF_FILE
  1032. if test 14436 -ne `wc -c <'desCode.h'`; then
  1033.     echo shar: \"'desCode.h'\" unpacked with wrong size!
  1034. fi
  1035. # end of 'desCode.h'
  1036. fi
  1037. if test -f 'desCore.h' -a "${1}" != "-c" ; then 
  1038.   echo shar: Will not clobber existing file \"'desCore.h'\"
  1039. else
  1040. echo shar: Extracting \"'desCore.h'\" \(731 characters\)
  1041. sed "s/^X//" >'desCore.h' <<'END_OF_FILE'
  1042. X/*
  1043. X *    des - fast & portable DES encryption & decryption.
  1044. X *    Copyright (C) 1992  Dana L. How
  1045. X *    Please see the file `README' for the complete copyright notice.
  1046. X */
  1047. X
  1048. X#ifndef    lint
  1049. Xstatic char desCore_hRcs[] = "$Id: desCore.h,v 1.10 1992/04/16 23:08:44 how E $";
  1050. X#endif
  1051. X
  1052. Xtypedef unsigned char byte, DesData[ 8];
  1053. Xtypedef unsigned long word, DesKeys[32];
  1054. X
  1055. Xextern int DesMethod();
  1056. Xextern void DesQuickInit(), DesQuickDone();
  1057. Xextern void DesQuickCoreEncrypt(), DesQuickFipsEncrypt();
  1058. Xextern void DesQuickCoreDecrypt(), DesQuickFipsDecrypt();
  1059. Xextern void DesSmallCoreEncrypt(), DesSmallFipsEncrypt();
  1060. Xextern void DesSmallCoreDecrypt(), DesSmallFipsDecrypt();
  1061. Xextern void (*DesCryptFuncs[])();
  1062. Xextern int des_key_sched(), des_ecb_encrypt();
  1063. END_OF_FILE
  1064. if test 731 -ne `wc -c <'desCore.h'`; then
  1065.     echo shar: \"'desCore.h'\" unpacked with wrong size!
  1066. fi
  1067. # end of 'desCore.h'
  1068. fi
  1069. if test -f 'desKerb.c' -a "${1}" != "-c" ; then 
  1070.   echo shar: Will not clobber existing file \"'desKerb.c'\"
  1071. else
  1072. echo shar: Extracting \"'desKerb.c'\" \(904 characters\)
  1073. sed "s/^X//" >'desKerb.c' <<'END_OF_FILE'
  1074. X/*
  1075. X *    des - fast & portable DES encryption & decryption.
  1076. X *    Copyright (C) 1992  Dana L. How
  1077. X *    Please see the file `README' for the complete copyright notice.
  1078. X */
  1079. X
  1080. X#ifndef    lint
  1081. Xstatic char desKerb_cRcs[] = "$Id: desKerb.c,v 1.3 1992/05/19 23:59:24 how E $";
  1082. X#endif
  1083. X
  1084. X#include    "desCore.h"
  1085. X
  1086. X
  1087. X/* permit the default style of des functions to be changed */
  1088. X
  1089. Xvoid (*DesCryptFuncs[2])() = { DesSmallFipsDecrypt, DesSmallFipsEncrypt };
  1090. X
  1091. X/* kerberos-compatible key schedule function */
  1092. X
  1093. Xint
  1094. Xdes_key_sched(k, s)
  1095. Xbyte * k;
  1096. Xword * s;
  1097. X{
  1098. X    return DesMethod(s, k);
  1099. X}
  1100. X
  1101. X/* kerberos-compatible des coding function */
  1102. X
  1103. Xint
  1104. Xdes_ecb_encrypt(s, d, r, e)
  1105. Xbyte * s, * d;
  1106. Xword * r;
  1107. Xint e;
  1108. X{
  1109. X    (*DesCryptFuncs[e])(d, r, s);
  1110. X    return 0;
  1111. X}
  1112. X
  1113. X/* also needs to be defined,  as pointed out by eay@psych.psy.uq.oz.au */
  1114. X
  1115. Xint
  1116. Xdes_encrypt(s, d, r, e)
  1117. Xbyte * s, * d;
  1118. Xword * r;
  1119. Xint e;
  1120. X{
  1121. X        (*DesCryptFuncs[e])(d, r, s);
  1122. X        return 0;
  1123. X}
  1124. END_OF_FILE
  1125. if test 904 -ne `wc -c <'desKerb.c'`; then
  1126.     echo shar: \"'desKerb.c'\" unpacked with wrong size!
  1127. fi
  1128. # end of 'desKerb.c'
  1129. fi
  1130. if test -f 'desQuick.c' -a "${1}" != "-c" ; then 
  1131.   echo shar: Will not clobber existing file \"'desQuick.c'\"
  1132. else
  1133. echo shar: Extracting \"'desQuick.c'\" \(1039 characters\)
  1134. sed "s/^X//" >'desQuick.c' <<'END_OF_FILE'
  1135. X/*
  1136. X *    des - fast & portable DES encryption & decryption.
  1137. X *    Copyright (C) 1992  Dana L. How
  1138. X *    Please see the file `README' for the complete copyright notice.
  1139. X */
  1140. X
  1141. X#ifndef    lint
  1142. Xstatic char desQuick_cRcs[] = "$Id: desQuick.c,v 1.5 1992/05/15 05:48:28 how E $";
  1143. X#endif
  1144. X
  1145. X#include    "desCore.h"
  1146. Xextern word des_keymap[];
  1147. X
  1148. X
  1149. X/* static information */
  1150. X
  1151. Xstatic depth = 0;        /* keep track of the request depth */
  1152. Xword des_bigmap[0x4000];    /* big lookup table */
  1153. X
  1154. X/* fill in the 64k table used by the `quick' option */
  1155. X
  1156. Xvoid
  1157. XDesQuickInit()
  1158. X{
  1159. X    int s1, s3, x;
  1160. X    word * t0, * t1, * t2, * t3;
  1161. X
  1162. X    if ( depth++ )
  1163. X        return;
  1164. X
  1165. X    t0 = des_bigmap;
  1166. X    t1 = t0 + 64;
  1167. X    t2 = t1 + 64;
  1168. X    t3 = t2 + 64;
  1169. X
  1170. X    for ( s3 = 63; s3 >= 0; s3-- ) {
  1171. X        for ( s1 = 63; s1 >= 0; s1-- ) {
  1172. X            x = (s3 << 8) | s1;
  1173. X            t3[x] = des_keymap[s3+128] ^ des_keymap[s1+192];
  1174. X            t1[x] = des_keymap[s3    ] ^ des_keymap[s1+ 64];
  1175. X            t2[x] = des_keymap[s3+384] ^ des_keymap[s1+448];
  1176. X            t0[x] = des_keymap[s3+256] ^ des_keymap[s1+320];
  1177. X        }
  1178. X    }
  1179. X}
  1180. X
  1181. X/* free the 64k table, if necessary */
  1182. X
  1183. Xvoid
  1184. XDesQuickDone()
  1185. X{
  1186. X}
  1187. END_OF_FILE
  1188. if test 1039 -ne `wc -c <'desQuick.c'`; then
  1189.     echo shar: \"'desQuick.c'\" unpacked with wrong size!
  1190. fi
  1191. # end of 'desQuick.c'
  1192. fi
  1193. if test -f 'desTest.c' -a "${1}" != "-c" ; then 
  1194.   echo shar: Will not clobber existing file \"'desTest.c'\"
  1195. else
  1196. echo shar: Extracting \"'desTest.c'\" \(4027 characters\)
  1197. sed "s/^X//" >'desTest.c' <<'END_OF_FILE'
  1198. X/*
  1199. X *    des - fast & portable DES encryption & decryption.
  1200. X *    Copyright (C) 1992  Dana L. How
  1201. X *    Please see the file `README' for the complete copyright notice.
  1202. X *
  1203. X *    Exercise the DES routines and collect performance statistics.
  1204. X */
  1205. X
  1206. X#ifndef    lint
  1207. Xstatic char desTest_cRcs[] = "$Id: desTest.c,v 1.10 1992/04/17 00:44:15 how E $";
  1208. X#endif
  1209. X
  1210. Xextern printf();
  1211. X
  1212. X#include    "desCore.h"
  1213. X
  1214. X/* define now(w) to be the elapsed time in hundredths of a second */
  1215. X
  1216. X#include    <sys/time.h>
  1217. X#include    <sys/resource.h>
  1218. Xextern getrusage();
  1219. Xstatic struct rusage usage;
  1220. X#define    now(w)    (                        \
  1221. X        (void)getrusage(RUSAGE_SELF, &usage),        \
  1222. X        usage.ru_utime.tv_sec  * 100 +            \
  1223. X        usage.ru_utime.tv_usec / 10000            \
  1224. X    )
  1225. X
  1226. X/* test data
  1227. X * the tests (key0-3, text0-3) are cribbed from code which is (c) 1988 MIT
  1228. X */
  1229. X
  1230. Xbyte keyt[8] =        {0x5d, 0x85, 0x91, 0x73, 0xcb, 0x49, 0xdf, 0x2f};
  1231. Xbyte key0[8] =        {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80};
  1232. Xbyte key1[8] =        {0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
  1233. Xbyte key2[8] =        {0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f};
  1234. Xbyte key3[8] =        {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  1235. Xbyte textt[8] =        {0x67, 0x1f, 0xc8, 0x93, 0x46, 0x5e, 0xab, 0x1e};
  1236. Xbyte text0[8] =        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  1237. Xbyte text1[8] =        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
  1238. Xbyte text2[8] =        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  1239. Xbyte text3[8] =        {'N',  'o',  'w',  ' ',  'i',  's',  ' ',  't' };
  1240. X
  1241. X/* work areas */
  1242. X
  1243. XDesKeys keys;
  1244. Xbyte cipher[8], output[8];
  1245. X
  1246. X/* noisy interfaces to the routines under test */
  1247. X
  1248. Xstatic void
  1249. Xmethod(key)
  1250. Xbyte *key;
  1251. X{
  1252. X    int j;
  1253. X
  1254. X    (void)printf("\nkey:\t");
  1255. X    for ( j = 0; j < 8; j++ )
  1256. X        (void)printf("%02X ", key[j]);
  1257. X    if ( des_key_sched(key, keys) )
  1258. X        (void)printf("W");
  1259. X    (void)printf("\t");
  1260. X}
  1261. X
  1262. Xstatic void
  1263. Xencode(src, dst)
  1264. Xbyte *src, *dst;
  1265. X{
  1266. X    int j;
  1267. X
  1268. X    (void)printf("clear:\t");
  1269. X    for (j = 0; j < 8; j++)
  1270. X        (void)printf("%02X ", src[j]);
  1271. X
  1272. X    (void)des_ecb_encrypt(src, dst, keys, 1);
  1273. X
  1274. X    (void)printf("\tcipher:\t");
  1275. X    for (j = 0; j < 8; j++)
  1276. X        (void)printf("%02X ", dst[j]);
  1277. X    (void)printf("\n");
  1278. X}
  1279. X
  1280. Xstatic void
  1281. Xdecode(src, dst)
  1282. Xbyte *src, *dst;
  1283. X{
  1284. X    int j;
  1285. X
  1286. X    (void)printf("cipher:\t");
  1287. X    for (j = 0; j < 8; j++)
  1288. X        (void)printf("%02X ", src[j]);
  1289. X
  1290. X    (void)des_ecb_encrypt(src, dst, keys, 0);
  1291. X
  1292. X    (void)printf("\tclear:\t");
  1293. X    for (j = 0; j < 8; j++)
  1294. X        (void)printf("%02X ", dst[j]);
  1295. X    (void)printf("\n");
  1296. X}
  1297. X
  1298. X/* run the tests */
  1299. X
  1300. Xint
  1301. Xmain()
  1302. X{
  1303. X    int j, m, e, n;
  1304. X    void (*f)();
  1305. X    static char * expect[] = {
  1306. X        "57 99 F7 2A D2 3F AE 4C", "9C C6 2D F4 3B 6E ED 74",
  1307. X        "90 E6 96 A2 AD 56 50 0D", "A3 80 E0 2A 6B E5 46 96",
  1308. X        "43 5C FF C5 68 B3 70 1D", "25 DD AC 3E 96 17 64 67",
  1309. X        "80 B5 07 E1 E6 A7 47 3D", "3F A4 0E 8A 98 4D 48 15",
  1310. X    };
  1311. X    static void (*funcs[])() = {
  1312. X        DesQuickCoreEncrypt, DesQuickFipsEncrypt,
  1313. X        DesSmallCoreEncrypt, DesSmallFipsEncrypt,
  1314. X        DesQuickCoreDecrypt, DesQuickFipsDecrypt,
  1315. X        DesSmallCoreDecrypt, DesSmallFipsDecrypt };
  1316. X    static char * names[] = {
  1317. X        "QuickCore", "QuickFips",
  1318. X        "SmallCore", "SmallFips" };
  1319. X
  1320. X    n = 0;
  1321. X    DesQuickInit();
  1322. X
  1323. X    /* do timing info first */
  1324. X
  1325. X    f = (void (*)())DesMethod;
  1326. X    j = 10000;
  1327. X    m = now(0);
  1328. X    do
  1329. X        (*f)(keys, keyt);
  1330. X    while ( --j );
  1331. X    m = now(1) - m;
  1332. X
  1333. X    do {
  1334. X            DesCryptFuncs[0] = funcs[n+4];
  1335. X        f = DesCryptFuncs[1] = funcs[n  ];
  1336. X        j = 100000;
  1337. X        e = now(0);
  1338. X        do
  1339. X            (*f)(cipher, keys, textt);
  1340. X        while ( --j );
  1341. X        e = now(1) - e;
  1342. X
  1343. X        (void)printf(    "%s:  setkey,%5duS;  encode,%3d.%1duS.\n",
  1344. X                names[n], m, e/10, e%10);
  1345. X
  1346. X        /* now check functionality */
  1347. X
  1348. X        method(key0);
  1349. X        (void)printf("cipher?\t%s\n", expect[(n % 2) + 0]);
  1350. X        encode(text0, cipher);
  1351. X        decode(cipher, output);
  1352. X
  1353. X        method(key1);
  1354. X        (void)printf("cipher?\t%s\n", expect[(n % 2) + 2]);
  1355. X        encode(text1, cipher);
  1356. X        decode(cipher, output);
  1357. X
  1358. X        method(key2);
  1359. X        (void)printf("cipher?\t%s\n", expect[(n % 2) + 4]);
  1360. X        encode(text2, cipher);
  1361. X        decode(cipher, output);
  1362. X
  1363. X        method(key3);
  1364. X        (void)printf("cipher?\t%s\n", expect[(n % 2) + 6]);
  1365. X        encode(text3, cipher);
  1366. X        decode(cipher, output);
  1367. X
  1368. X        (void)printf("%c", "\n\f\n\0"[n]);
  1369. X
  1370. X    } while ( ++n < 4 );
  1371. X
  1372. X    DesQuickDone();
  1373. X    return 0;
  1374. X}
  1375. END_OF_FILE
  1376. if test 4027 -ne `wc -c <'desTest.c'`; then
  1377.     echo shar: \"'desTest.c'\" unpacked with wrong size!
  1378. fi
  1379. # end of 'desTest.c'
  1380. fi
  1381. if test -f 'desUtil.c' -a "${1}" != "-c" ; then 
  1382.   echo shar: Will not clobber existing file \"'desUtil.c'\"
  1383. else
  1384. echo shar: Extracting \"'desUtil.c'\" \(4296 characters\)
  1385. sed "s/^X//" >'desUtil.c' <<'END_OF_FILE'
  1386. X/*
  1387. X *    des - fast & portable DES encryption & decryption.
  1388. X *    Copyright (C) 1992  Dana L. How
  1389. X *    Please see the file `README' for the complete copyright notice.
  1390. X */
  1391. X
  1392. X#ifndef    lint
  1393. Xstatic char desUtil_cRcs[] = "$Id: desUtil.c,v 1.13 1992/05/15 07:58:20 how E $";
  1394. X#endif
  1395. X
  1396. X#include    "desCode.h"
  1397. X
  1398. X
  1399. X/* various tables */
  1400. X
  1401. Xword des_keymap[] = {
  1402. X#include    "keymap.h"
  1403. X};
  1404. X
  1405. Xstatic byte rotors[] = {
  1406. X#include    "rotors.h"
  1407. X};
  1408. Xstatic char parity[] = {
  1409. X#include    "parity.h"
  1410. X};
  1411. X
  1412. X#ifndef    lint
  1413. Xstatic char ego[] = "\n\nFast DES Library Copyright (c) 1991 Dana L. How\n\n";
  1414. X#endif
  1415. X
  1416. X
  1417. X/* set up the method list from the key */
  1418. X
  1419. Xint
  1420. XDesMethod(method, k)
  1421. Xregister word * method;
  1422. Xregister byte * k;
  1423. X{
  1424. X    register word n, w;
  1425. X    register char * b0, * b1;
  1426. X    char bits0[56], bits1[56];
  1427. X
  1428. X    /* check for bad parity and weak keys */
  1429. X    b0 = parity;
  1430. X    n  = b0[k[0]]; n <<= 4;
  1431. X    n |= b0[k[1]]; n <<= 4;
  1432. X    n |= b0[k[2]]; n <<= 4;
  1433. X    n |= b0[k[3]]; n <<= 4;
  1434. X    n |= b0[k[4]]; n <<= 4;
  1435. X    n |= b0[k[5]]; n <<= 4;
  1436. X    n |= b0[k[6]]; n <<= 4;
  1437. X    n |= b0[k[7]];
  1438. X    w  = 0X88888888L;
  1439. X    /* report bad parity in key */
  1440. X    if ( n & w )
  1441. X        return -1;
  1442. X    /* report a weak or semi-weak key */
  1443. X    if ( !((n - (w >> 3)) & w) ) {    /* 1 in 10^10 keys passes this test */
  1444. X        if ( n < 0X41415151 ) {
  1445. X            if ( n < 0X31312121 ) {
  1446. X                if ( n < 0X14141515 ) {
  1447. X                    /* 01 01 01 01 01 01 01 01 */
  1448. X                    if ( n == 0X11111111 ) return -2;
  1449. X                    /* 01 1F 01 1F 01 0E 01 0E */
  1450. X                    if ( n == 0X13131212 ) return -2;
  1451. X                } else {
  1452. X                    /* 01 E0 01 E0 01 F1 01 F1 */
  1453. X                    if ( n == 0X14141515 ) return -2;
  1454. X                    /* 01 FE 01 FE 01 FE 01 FE */
  1455. X                    if ( n == 0X16161616 ) return -2;
  1456. X                }
  1457. X            } else {
  1458. X                if ( n < 0X34342525 ) {
  1459. X                    /* 1F 01 1F 01 0E 01 0E 01 */
  1460. X                    if ( n == 0X31312121 ) return -2;
  1461. X                    /* 1F 1F 1F 1F 0E 0E 0E 0E */    /* ? */
  1462. X                    if ( n == 0X33332222 ) return -2;
  1463. X                } else {
  1464. X                    /* 1F E0 1F E0 0E F1 0E F1 */
  1465. X                    if ( n == 0X34342525 ) return -2;
  1466. X                    /* 1F FE 1F FE 0E FE 0E FE */
  1467. X                    if ( n == 0X36362626 ) return -2;
  1468. X                }
  1469. X            }
  1470. X        } else {
  1471. X            if ( n < 0X61616161 ) {
  1472. X                if ( n < 0X44445555 ) {
  1473. X                    /* E0 01 E0 01 F1 01 F1 01 */
  1474. X                    if ( n == 0X41415151 ) return -2;
  1475. X                    /* E0 1F E0 1F F1 0E F1 0E */
  1476. X                    if ( n == 0X43435252 ) return -2;
  1477. X                } else {
  1478. X                    /* E0 E0 E0 E0 F1 F1 F1 F1 */    /* ? */
  1479. X                    if ( n == 0X44445555 ) return -2;
  1480. X                    /* E0 FE E0 FE F1 FE F1 FE */
  1481. X                    if ( n == 0X46465656 ) return -2;
  1482. X                }
  1483. X            } else {
  1484. X                if ( n < 0X64646565 ) {
  1485. X                    /* FE 01 FE 01 FE 01 FE 01 */
  1486. X                    if ( n == 0X61616161 ) return -2;
  1487. X                    /* FE 1F FE 1F FE 0E FE 0E */
  1488. X                    if ( n == 0X63636262 ) return -2;
  1489. X                } else {
  1490. X                    /* FE E0 FE E0 FE F1 FE F1 */
  1491. X                    if ( n == 0X64646565 ) return -2;
  1492. X                    /* FE FE FE FE FE FE FE FE */
  1493. X                    if ( n == 0X66666666 ) return -2;
  1494. X                }
  1495. X            }
  1496. X        }
  1497. X    }
  1498. X
  1499. X    /* explode the bits */
  1500. X    n = 56;
  1501. X    b0 = bits0;
  1502. X    b1 = bits1;
  1503. X    do {
  1504. X        w = (256 | *k++) << 2;
  1505. X        do {
  1506. X            --n;
  1507. X            b1[n] = 8 & w;
  1508. X            w >>= 1;
  1509. X            b0[n] = 4 & w;
  1510. X        } while ( w >= 16 );
  1511. X    } while ( n );
  1512. X
  1513. X    /* put the bits in the correct places */
  1514. X    /* the inclusion of constant bits is inspired by ideas and code
  1515. X     * from Richard Outerbridge;  see desCode.h for how they're used */
  1516. X    n = 16;
  1517. X    k = rotors;
  1518. X    do {
  1519. X        w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
  1520. X        w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
  1521. X        w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
  1522. X        w <<= 8;
  1523. X        w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
  1524. X        w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
  1525. X        w  |=  b1[k[10   ]] | b0[k[11   ]];
  1526. X        w <<= 8;
  1527. X        w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
  1528. X        w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
  1529. X        w  |=  b1[k[16   ]] | b0[k[17   ]];
  1530. X        w <<= 8;
  1531. X        w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
  1532. X        w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
  1533. X        w  |=  b1[k[22   ]] | b0[k[23   ]];
  1534. X
  1535. X        method[0] = w | 0X01020300L;
  1536. X
  1537. X        w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
  1538. X        w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
  1539. X        w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
  1540. X        w <<= 8;
  1541. X        w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
  1542. X        w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
  1543. X        w  |=  b1[k[10+24]] | b0[k[11+24]];
  1544. X        w <<= 8;
  1545. X        w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
  1546. X        w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
  1547. X        w  |=  b1[k[16+24]] | b0[k[17+24]];
  1548. X        w <<= 8;
  1549. X        w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
  1550. X        w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
  1551. X        w  |=  b1[k[22+24]] | b0[k[23+24]];
  1552. X
  1553. X        method[1] = w | 0X01020300L;
  1554. X
  1555. X        k    += 48;
  1556. X        method    += 2;
  1557. X    } while ( --n );
  1558. X
  1559. X    return 0;
  1560. X}
  1561. END_OF_FILE
  1562. if test 4296 -ne `wc -c <'desUtil.c'`; then
  1563.     echo shar: \"'desUtil.c'\" unpacked with wrong size!
  1564. fi
  1565. # end of 'desUtil.c'
  1566. fi
  1567. if test -f 'desdata.c' -a "${1}" != "-c" ; then 
  1568.   echo shar: Will not clobber existing file \"'desdata.c'\"
  1569. else
  1570. echo shar: Extracting \"'desdata.c'\" \(4512 characters\)
  1571. sed "s/^X//" >'desdata.c' <<'END_OF_FILE'
  1572. X/*
  1573. X *    des - fast & portable DES encryption & decryption.
  1574. X *    Copyright (C) 1992  Dana L. How
  1575. X *    Please see the file `README' for the complete copyright notice.
  1576. X *
  1577. X *    Generate tables used by desUtil.c and desCode.h.
  1578. X */
  1579. X
  1580. X#ifndef    lint
  1581. Xstatic char desdata_cRcs[] = "$Id: desdata.c,v 1.11 1992/05/15 05:47:37 how E $";
  1582. X#endif
  1583. X
  1584. X#include    "desinfo.h"
  1585. X
  1586. X#include    "desCode.h"
  1587. X
  1588. X/* list of weak and semi-weak keys
  1589. X
  1590. X     +0   +1   +2   +3   +4   +5   +6   +7
  1591. X    0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
  1592. X    0x01 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e
  1593. X    0x01 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1
  1594. X    0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe
  1595. X    0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e 0x01
  1596. X    0x1f 0x1f 0x1f 0x1f 0x0e 0x0e 0x0e 0x0e
  1597. X    0x1f 0xe0 0x1f 0xe0 0x0e 0xf1 0x0e 0xf1
  1598. X    0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e 0xfe
  1599. X    0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 0x01
  1600. X    0xe0 0x1f 0xe0 0x1f 0xf1 0x0e 0xf1 0x0e
  1601. X    0xe0 0xe0 0xe0 0xe0 0xf1 0xf1 0xf1 0xf1
  1602. X    0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 0xfe
  1603. X    0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01
  1604. X    0xfe 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e
  1605. X    0xfe 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1
  1606. X    0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe
  1607. X */
  1608. X
  1609. X/* key bit order in each method pair: bits 31->00 of 1st, bits 31->00 of 2nd */
  1610. X/* this does not reflect the rotate of the 2nd word */
  1611. X
  1612. X#define    S(box,bit)    (box*6+bit)
  1613. Xint korder[] = {
  1614. X    S(7, 5), S(7, 4), S(7, 3), S(7, 2), S(7, 1), S(7, 0),
  1615. X    S(5, 5), S(5, 4), S(5, 3), S(5, 2), S(5, 1), S(5, 0),
  1616. X    S(3, 5), S(3, 4), S(3, 3), S(3, 2), S(3, 1), S(3, 0),
  1617. X    S(1, 5), S(1, 4), S(1, 3), S(1, 2), S(1, 1), S(1, 0),
  1618. X    S(6, 5), S(6, 4), S(6, 3), S(6, 2), S(6, 1), S(6, 0),
  1619. X    S(4, 5), S(4, 4), S(4, 3), S(4, 2), S(4, 1), S(4, 0),
  1620. X    S(2, 5), S(2, 4), S(2, 3), S(2, 2), S(2, 1), S(2, 0),
  1621. X    S(0, 5), S(0, 4), S(0, 3), S(0, 2), S(0, 1), S(0, 0),
  1622. X};
  1623. X
  1624. X/* the order in which the algorithm accesses the s boxes */
  1625. X
  1626. Xint sorder[] = {
  1627. X    7, 5, 3, 1, 6, 4, 2, 0,
  1628. X};
  1629. X
  1630. Xint
  1631. Xmain(argc, argv)
  1632. Xint argc;
  1633. Xchar *argv[];
  1634. X{
  1635. X    word d, i, j, k, l, m, n, s;
  1636. X    char b[256], ksr[56];
  1637. X    extern printf();
  1638. X
  1639. X    switch ( argv[1][0] ) {
  1640. X
  1641. X    /*
  1642. X     * <<< make the key parity table >>>
  1643. X     */
  1644. X
  1645. Xcase 'p':
  1646. X    (void)printf(
  1647. X"/* automagically produced - do not fuss with this information */\n\n");
  1648. X
  1649. X    /* store parity information */
  1650. X    for ( i = 0; i < 256; i++ ) {
  1651. X        j  = i;
  1652. X        j ^= j >> 4;    /* bits 3-0 have pairs */
  1653. X        j ^= j << 2;    /* bits 3-2 have quads */
  1654. X        j ^= j << 1;    /* bit  3 has the entire eight (no cox) */
  1655. X        b[i] = 8 & ~j;    /* 0 is okay and 8 is bad parity */
  1656. X    }
  1657. X
  1658. X    /* only these characters can appear in a weak key */
  1659. X    b[0x01] = 1;
  1660. X    b[0x0e] = 2;
  1661. X    b[0x1f] = 3;
  1662. X    b[0xe0] = 4;
  1663. X    b[0xf1] = 5;
  1664. X    b[0xfe] = 6;
  1665. X
  1666. X    /* print it out */
  1667. X    for ( i = 0; i < 256; i++ ) {
  1668. X        (void)printf("%d,", b[i]);
  1669. X        if ( (i & 31) == 31 )
  1670. X            (void)printf("\n");
  1671. X    }
  1672. X
  1673. X    break;
  1674. X
  1675. X
  1676. X    /*
  1677. X     * <<< make the key usage table >>>
  1678. X     */
  1679. X
  1680. Xcase 'r':
  1681. X    (void)printf("/* automagically made - do not fuss with this */\n\n");
  1682. X
  1683. X    /* KL specifies the initial key bit positions */
  1684. X    for (i = 0; i < 56; i++)
  1685. X        ksr[i] = (KL[i] - 1) ^ 7;
  1686. X
  1687. X    for (i = 0; i < 16; i++) {
  1688. X
  1689. X        /* apply the appropriate number of left shifts */
  1690. X        for (j = 0; j < KS[i]; j++) {
  1691. X            m = ksr[ 0];
  1692. X            n = ksr[28];
  1693. X            for (k = 0; k < 27; k++)
  1694. X                ksr[k     ] = ksr[k +  1],
  1695. X                ksr[k + 28] = ksr[k + 29];
  1696. X            ksr[27] = m;
  1697. X            ksr[55] = n;
  1698. X        }
  1699. X
  1700. X        /* output the key bit numbers */
  1701. X        for (j = 0; j < 48; j++) {
  1702. X            m = ksr[KC[korder[j]] - 1];
  1703. X            m = (m / 8) * 7 + (m % 8) - 1;
  1704. X            m = 55 - m;
  1705. X            (void)printf(" %2d,", m);
  1706. X            if ((j % 12) == 11)
  1707. X                (void)printf("\n");
  1708. X        }
  1709. X        (void)printf("\n");
  1710. X    }
  1711. X
  1712. X    break;
  1713. X
  1714. X
  1715. X    /*
  1716. X     * <<< make the keymap table >>>
  1717. X     */
  1718. X
  1719. Xcase 'k':
  1720. X    (void)printf("/* automagically made - do not fuss with this */\n\n");
  1721. X
  1722. X    for ( i = 0; i <= 7 ; i++ ) {
  1723. X        s = sorder[i];
  1724. X        for ( d = 0; d <= 63; d++ ) {
  1725. X            /* flip bits */
  1726. X            k =    ((d << 5) & 32) |
  1727. X                ((d << 3) & 16) |
  1728. X                ((d << 1) &  8) |
  1729. X                ((d >> 1) &  4) |
  1730. X                ((d >> 3) &  2) |
  1731. X                ((d >> 5) &  1) ;
  1732. X            /* more bit twiddling */
  1733. X            l =    ((k << 0) & 32) |    /* overlap bit */
  1734. X                ((k << 4) & 16) |    /* overlap bit */
  1735. X                ((k >> 1) & 15) ;    /* unique bits */
  1736. X            /* look up s box value */
  1737. X            m = SB[s][l];
  1738. X            /* flip bits */
  1739. X            n =    ((m << 3) &  8) |
  1740. X                ((m << 1) &  4) |
  1741. X                ((m >> 1) &  2) |
  1742. X                ((m >> 3) &  1) ;
  1743. X            /* put in correct nybble */
  1744. X            n <<= (s << 2);
  1745. X            /* perform p permutation */
  1746. X            for ( m = j = 0; j < 32; j++ )
  1747. X                if ( n & (1 << (SP[j] - 1)) )
  1748. X                    m |= (1 << j);
  1749. X            /* rotate right (alg keeps everything rotated by 1) */
  1750. X            ROR1(m);
  1751. X            /* print it out */
  1752. X            (void)printf(" 0x%08lx,", m);
  1753. X            if ( ( d & 3 ) == 3 )
  1754. X                (void)printf("\n");
  1755. X        }
  1756. X        (void)printf("\n");
  1757. X    }
  1758. X
  1759. X    break;
  1760. X
  1761. X    }
  1762. X
  1763. X    return 0;
  1764. X}
  1765. END_OF_FILE
  1766. if test 4512 -ne `wc -c <'desdata.c'`; then
  1767.     echo shar: \"'desdata.c'\" unpacked with wrong size!
  1768. fi
  1769. # end of 'desdata.c'
  1770. fi
  1771. if test -f 'desinfo.h' -a "${1}" != "-c" ; then 
  1772.   echo shar: Will not clobber existing file \"'desinfo.h'\"
  1773. else
  1774. echo shar: Extracting \"'desinfo.h'\" \(3506 characters\)
  1775. sed "s/^X//" >'desinfo.h' <<'END_OF_FILE'
  1776. X/*
  1777. X *    des - fast & portable DES encryption & decryption.
  1778. X *    Copyright (C) 1992  Dana L. How
  1779. X *    Please see the file `README' for the complete copyright notice.
  1780. X *
  1781. X *    Tables describing DES rather than just this implementation.
  1782. X *    These are used in desdata but NOT in runtime code.
  1783. X */
  1784. X
  1785. X#ifndef    lint
  1786. Xstatic char desinfo_hRcs[] = "$Id: desinfo.h,v 1.3 1992/04/16 23:08:44 how E $";
  1787. X#endif
  1788. X
  1789. X/* the initial permutation, E selection, and final permutation are hardwired */
  1790. X
  1791. X/* Key Load: how to load the shift register from the user key */
  1792. X
  1793. Xchar KL[] = {
  1794. X
  1795. X    57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
  1796. X    10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
  1797. X
  1798. X    63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
  1799. X    14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4,
  1800. X};
  1801. X
  1802. X/* Key Shift: how many times to shift the key shift register */
  1803. X
  1804. Xchar KS[] = {
  1805. X
  1806. X    1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
  1807. X};
  1808. X
  1809. X/* Key Choose: which key bits from shift reg are used in the key schedule */
  1810. X
  1811. Xchar KC[] = {
  1812. X
  1813. X    14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
  1814. X    23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
  1815. X
  1816. X    41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
  1817. X    44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,
  1818. X};
  1819. X
  1820. X/* S Boxes */
  1821. X
  1822. Xchar SB[8][64] = {
  1823. X
  1824. X    14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  1825. X     0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  1826. X     4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  1827. X    15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  1828. X
  1829. X    15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  1830. X     3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  1831. X     0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  1832. X    13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  1833. X
  1834. X    10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  1835. X    13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  1836. X    13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  1837. X     1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  1838. X
  1839. X     7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  1840. X    13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  1841. X    10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  1842. X     3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  1843. X
  1844. X     2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  1845. X    14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  1846. X     4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  1847. X    11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  1848. X
  1849. X    12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  1850. X    10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  1851. X     9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  1852. X     4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  1853. X
  1854. X     4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  1855. X    13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  1856. X     1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  1857. X     6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  1858. X
  1859. X    13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  1860. X     1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  1861. X     7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  1862. X     2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
  1863. X};
  1864. X
  1865. X/* Sbox Permutation */
  1866. X
  1867. Xchar SP[] = {    
  1868. X
  1869. X    16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
  1870. X     2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25,
  1871. X};
  1872. END_OF_FILE
  1873. if test 3506 -ne `wc -c <'desinfo.h'`; then
  1874.     echo shar: \"'desinfo.h'\" unpacked with wrong size!
  1875. fi
  1876. # end of 'desinfo.h'
  1877. fi
  1878. echo shar: End of archive 1 \(of 1\).
  1879. cp /dev/null ark1isdone
  1880. MISSING=""
  1881. for I in 1 ; do
  1882.     if test ! -f ark${I}isdone ; then
  1883.     MISSING="${MISSING} ${I}"
  1884.     fi
  1885. done
  1886. if test "${MISSING}" = "" ; then
  1887.     echo You have the archive.
  1888.     echo "now run make"
  1889.     rm -f ark[1-9]isdone
  1890. else
  1891.     echo You still need to unpack the following archives:
  1892.     echo "        " ${MISSING}
  1893. fi
  1894. ##  End of shell archive.
  1895. exit 0
  1896. exit 0 # Just in case...
  1897.