des_opts.c revision 296465
1/* crypto/des/des_opts.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/*
60 * define PART1, PART2, PART3 or PART4 to build only with a few of the
61 * options. This is for machines with 64k code segment size restrictions.
62 */
63
64#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
65# define TIMES
66#endif
67
68#include <stdio.h>
69#ifndef OPENSSL_SYS_MSDOS
70# include <openssl/e_os2.h>
71# include OPENSSL_UNISTD
72#else
73# include <io.h>
74extern void exit();
75#endif
76
77#ifndef OPENSSL_SYS_NETWARE
78# include <signal.h>
79#endif
80
81#ifndef _IRIX
82# include <time.h>
83#endif
84#ifdef TIMES
85# include <sys/types.h>
86# include <sys/times.h>
87#endif
88
89/*
90 * Depending on the VMS version, the tms structure is perhaps defined. The
91 * __TMS macro will show if it was.  If it wasn't defined, we should undefine
92 * TIMES, since that tells the rest of the program how things should be
93 * handled.  -- Richard Levitte
94 */
95#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
96# undef TIMES
97#endif
98
99#ifndef TIMES
100# include <sys/timeb.h>
101#endif
102
103#if defined(sun) || defined(__ultrix)
104# define _POSIX_SOURCE
105# include <limits.h>
106# include <sys/param.h>
107#endif
108
109#include <openssl/des.h>
110#include "spr.h"
111
112#define DES_DEFAULT_OPTIONS
113
114#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
115# define PART1
116# define PART2
117# define PART3
118# define PART4
119#endif
120
121#ifdef PART1
122
123# undef DES_UNROLL
124# undef DES_RISC1
125# undef DES_RISC2
126# undef DES_PTR
127# undef D_ENCRYPT
128# define DES_encrypt1 des_encrypt_u4_cisc_idx
129# define DES_encrypt2 des_encrypt2_u4_cisc_idx
130# define DES_encrypt3 des_encrypt3_u4_cisc_idx
131# define DES_decrypt3 des_decrypt3_u4_cisc_idx
132# undef HEADER_DES_LOCL_H
133# include "des_enc.c"
134
135# define DES_UNROLL
136# undef DES_RISC1
137# undef DES_RISC2
138# undef DES_PTR
139# undef D_ENCRYPT
140# undef DES_encrypt1
141# undef DES_encrypt2
142# undef DES_encrypt3
143# undef DES_decrypt3
144# define DES_encrypt1 des_encrypt_u16_cisc_idx
145# define DES_encrypt2 des_encrypt2_u16_cisc_idx
146# define DES_encrypt3 des_encrypt3_u16_cisc_idx
147# define DES_decrypt3 des_decrypt3_u16_cisc_idx
148# undef HEADER_DES_LOCL_H
149# include "des_enc.c"
150
151# undef DES_UNROLL
152# define DES_RISC1
153# undef DES_RISC2
154# undef DES_PTR
155# undef D_ENCRYPT
156# undef DES_encrypt1
157# undef DES_encrypt2
158# undef DES_encrypt3
159# undef DES_decrypt3
160# define DES_encrypt1 des_encrypt_u4_risc1_idx
161# define DES_encrypt2 des_encrypt2_u4_risc1_idx
162# define DES_encrypt3 des_encrypt3_u4_risc1_idx
163# define DES_decrypt3 des_decrypt3_u4_risc1_idx
164# undef HEADER_DES_LOCL_H
165# include "des_enc.c"
166
167#endif
168
169#ifdef PART2
170
171# undef DES_UNROLL
172# undef DES_RISC1
173# define DES_RISC2
174# undef DES_PTR
175# undef D_ENCRYPT
176# undef DES_encrypt1
177# undef DES_encrypt2
178# undef DES_encrypt3
179# undef DES_decrypt3
180# define DES_encrypt1 des_encrypt_u4_risc2_idx
181# define DES_encrypt2 des_encrypt2_u4_risc2_idx
182# define DES_encrypt3 des_encrypt3_u4_risc2_idx
183# define DES_decrypt3 des_decrypt3_u4_risc2_idx
184# undef HEADER_DES_LOCL_H
185# include "des_enc.c"
186
187# define DES_UNROLL
188# define DES_RISC1
189# undef DES_RISC2
190# undef DES_PTR
191# undef D_ENCRYPT
192# undef DES_encrypt1
193# undef DES_encrypt2
194# undef DES_encrypt3
195# undef DES_decrypt3
196# define DES_encrypt1 des_encrypt_u16_risc1_idx
197# define DES_encrypt2 des_encrypt2_u16_risc1_idx
198# define DES_encrypt3 des_encrypt3_u16_risc1_idx
199# define DES_decrypt3 des_decrypt3_u16_risc1_idx
200# undef HEADER_DES_LOCL_H
201# include "des_enc.c"
202
203# define DES_UNROLL
204# undef DES_RISC1
205# define DES_RISC2
206# undef DES_PTR
207# undef D_ENCRYPT
208# undef DES_encrypt1
209# undef DES_encrypt2
210# undef DES_encrypt3
211# undef DES_decrypt3
212# define DES_encrypt1 des_encrypt_u16_risc2_idx
213# define DES_encrypt2 des_encrypt2_u16_risc2_idx
214# define DES_encrypt3 des_encrypt3_u16_risc2_idx
215# define DES_decrypt3 des_decrypt3_u16_risc2_idx
216# undef HEADER_DES_LOCL_H
217# include "des_enc.c"
218
219#endif
220
221#ifdef PART3
222
223# undef DES_UNROLL
224# undef DES_RISC1
225# undef DES_RISC2
226# define DES_PTR
227# undef D_ENCRYPT
228# undef DES_encrypt1
229# undef DES_encrypt2
230# undef DES_encrypt3
231# undef DES_decrypt3
232# define DES_encrypt1 des_encrypt_u4_cisc_ptr
233# define DES_encrypt2 des_encrypt2_u4_cisc_ptr
234# define DES_encrypt3 des_encrypt3_u4_cisc_ptr
235# define DES_decrypt3 des_decrypt3_u4_cisc_ptr
236# undef HEADER_DES_LOCL_H
237# include "des_enc.c"
238
239# define DES_UNROLL
240# undef DES_RISC1
241# undef DES_RISC2
242# define DES_PTR
243# undef D_ENCRYPT
244# undef DES_encrypt1
245# undef DES_encrypt2
246# undef DES_encrypt3
247# undef DES_decrypt3
248# define DES_encrypt1 des_encrypt_u16_cisc_ptr
249# define DES_encrypt2 des_encrypt2_u16_cisc_ptr
250# define DES_encrypt3 des_encrypt3_u16_cisc_ptr
251# define DES_decrypt3 des_decrypt3_u16_cisc_ptr
252# undef HEADER_DES_LOCL_H
253# include "des_enc.c"
254
255# undef DES_UNROLL
256# define DES_RISC1
257# undef DES_RISC2
258# define DES_PTR
259# undef D_ENCRYPT
260# undef DES_encrypt1
261# undef DES_encrypt2
262# undef DES_encrypt3
263# undef DES_decrypt3
264# define DES_encrypt1 des_encrypt_u4_risc1_ptr
265# define DES_encrypt2 des_encrypt2_u4_risc1_ptr
266# define DES_encrypt3 des_encrypt3_u4_risc1_ptr
267# define DES_decrypt3 des_decrypt3_u4_risc1_ptr
268# undef HEADER_DES_LOCL_H
269# include "des_enc.c"
270
271#endif
272
273#ifdef PART4
274
275# undef DES_UNROLL
276# undef DES_RISC1
277# define DES_RISC2
278# define DES_PTR
279# undef D_ENCRYPT
280# undef DES_encrypt1
281# undef DES_encrypt2
282# undef DES_encrypt3
283# undef DES_decrypt3
284# define DES_encrypt1 des_encrypt_u4_risc2_ptr
285# define DES_encrypt2 des_encrypt2_u4_risc2_ptr
286# define DES_encrypt3 des_encrypt3_u4_risc2_ptr
287# define DES_decrypt3 des_decrypt3_u4_risc2_ptr
288# undef HEADER_DES_LOCL_H
289# include "des_enc.c"
290
291# define DES_UNROLL
292# define DES_RISC1
293# undef DES_RISC2
294# define DES_PTR
295# undef D_ENCRYPT
296# undef DES_encrypt1
297# undef DES_encrypt2
298# undef DES_encrypt3
299# undef DES_decrypt3
300# define DES_encrypt1 des_encrypt_u16_risc1_ptr
301# define DES_encrypt2 des_encrypt2_u16_risc1_ptr
302# define DES_encrypt3 des_encrypt3_u16_risc1_ptr
303# define DES_decrypt3 des_decrypt3_u16_risc1_ptr
304# undef HEADER_DES_LOCL_H
305# include "des_enc.c"
306
307# define DES_UNROLL
308# undef DES_RISC1
309# define DES_RISC2
310# define DES_PTR
311# undef D_ENCRYPT
312# undef DES_encrypt1
313# undef DES_encrypt2
314# undef DES_encrypt3
315# undef DES_decrypt3
316# define DES_encrypt1 des_encrypt_u16_risc2_ptr
317# define DES_encrypt2 des_encrypt2_u16_risc2_ptr
318# define DES_encrypt3 des_encrypt3_u16_risc2_ptr
319# define DES_decrypt3 des_decrypt3_u16_risc2_ptr
320# undef HEADER_DES_LOCL_H
321# include "des_enc.c"
322
323#endif
324
325/* The following if from times(3) man page.  It may need to be changed */
326#ifndef HZ
327# ifndef CLK_TCK
328#  ifndef _BSD_CLK_TCK_         /* FreeBSD fix */
329#   define HZ   100.0
330#  else                         /* _BSD_CLK_TCK_ */
331#   define HZ ((double)_BSD_CLK_TCK_)
332#  endif
333# else                          /* CLK_TCK */
334#  define HZ ((double)CLK_TCK)
335# endif
336#endif
337
338#define BUFSIZE ((long)1024)
339long run = 0;
340
341double Time_F(int s);
342#ifdef SIGALRM
343# if defined(__STDC__) || defined(sgi)
344#  define SIGRETTYPE void
345# else
346#  define SIGRETTYPE int
347# endif
348
349SIGRETTYPE sig_done(int sig);
350SIGRETTYPE sig_done(int sig)
351{
352    signal(SIGALRM, sig_done);
353    run = 0;
354# ifdef LINT
355    sig = sig;
356# endif
357}
358#endif
359
360#define START   0
361#define STOP    1
362
363double Time_F(int s)
364{
365    double ret;
366#ifdef TIMES
367    static struct tms tstart, tend;
368
369    if (s == START) {
370        times(&tstart);
371        return (0);
372    } else {
373        times(&tend);
374        ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ;
375        return ((ret == 0.0) ? 1e-6 : ret);
376    }
377#else                           /* !times() */
378    static struct timeb tstart, tend;
379    long i;
380
381    if (s == START) {
382        ftime(&tstart);
383        return (0);
384    } else {
385        ftime(&tend);
386        i = (long)tend.millitm - (long)tstart.millitm;
387        ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0;
388        return ((ret == 0.0) ? 1e-6 : ret);
389    }
390#endif
391}
392
393#ifdef SIGALRM
394# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
395#else
396# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
397#endif
398
399#define time_it(func,name,index) \
400        print_name(name); \
401        Time_F(START); \
402        for (count=0,run=1; COND(cb); count++) \
403                { \
404                unsigned long d[2]; \
405                func(d,&sch,DES_ENCRYPT); \
406                } \
407        tm[index]=Time_F(STOP); \
408        fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
409        tm[index]=((double)COUNT(cb))/tm[index];
410
411#define print_it(name,index) \
412        fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
413                tm[index]*8,1.0e6/tm[index]);
414
415int main(int argc, char **argv)
416{
417    long count;
418    static unsigned char buf[BUFSIZE];
419    static DES_cblock key =
420        { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
421    static DES_cblock key2 =
422        { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 };
423    static DES_cblock key3 =
424        { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 };
425    DES_key_schedule sch, sch2, sch3;
426    double d, tm[16], max = 0;
427    int rank[16];
428    char *str[16];
429    int max_idx = 0, i, num = 0, j;
430#ifndef SIGALARM
431    long ca, cb, cc, cd, ce;
432#endif
433
434    for (i = 0; i < 12; i++) {
435        tm[i] = 0.0;
436        rank[i] = 0;
437    }
438
439#ifndef TIMES
440    fprintf(stderr, "To get the most accurate results, try to run this\n");
441    fprintf(stderr, "program when this computer is idle.\n");
442#endif
443
444    DES_set_key_unchecked(&key, &sch);
445    DES_set_key_unchecked(&key2, &sch2);
446    DES_set_key_unchecked(&key3, &sch3);
447
448#ifndef SIGALRM
449    fprintf(stderr, "First we calculate the approximate speed ...\n");
450    DES_set_key_unchecked(&key, sch);
451    count = 10;
452    do {
453        long i;
454        unsigned long data[2];
455
456        count *= 2;
457        Time_F(START);
458        for (i = count; i; i--)
459            DES_encrypt1(data, &(sch[0]), DES_ENCRYPT);
460        d = Time_F(STOP);
461    } while (d < 3.0);
462    ca = count;
463    cb = count * 3;
464    cc = count * 3 * 8 / BUFSIZE + 1;
465    cd = count * 8 / BUFSIZE + 1;
466
467    ce = count / 20 + 1;
468# define COND(d) (count != (d))
469# define COUNT(d) (d)
470#else
471# define COND(c) (run)
472# define COUNT(d) (count)
473    signal(SIGALRM, sig_done);
474    alarm(10);
475#endif
476
477#ifdef PART1
478    time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx  ", 0);
479    time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
480    time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
481    num += 3;
482#endif
483#ifdef PART2
484    time_it(des_encrypt_u16_risc1_idx, "des_encrypt_u16_risc1_idx", 3);
485    time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
486    time_it(des_encrypt_u16_risc2_idx, "des_encrypt_u16_risc2_idx", 5);
487    num += 3;
488#endif
489#ifdef PART3
490    time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr  ", 6);
491    time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
492    time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
493    num += 3;
494#endif
495#ifdef PART4
496    time_it(des_encrypt_u16_risc1_ptr, "des_encrypt_u16_risc1_ptr", 9);
497    time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ", 10);
498    time_it(des_encrypt_u16_risc2_ptr, "des_encrypt_u16_risc2_ptr", 11);
499    num += 3;
500#endif
501
502#ifdef PART1
503    str[0] = " 4  c i";
504    print_it("des_encrypt_u4_cisc_idx  ", 0);
505    max = tm[0];
506    max_idx = 0;
507    str[1] = "16  c i";
508    print_it("des_encrypt_u16_cisc_idx ", 1);
509    if (max < tm[1]) {
510        max = tm[1];
511        max_idx = 1;
512    }
513    str[2] = " 4 r1 i";
514    print_it("des_encrypt_u4_risc1_idx ", 2);
515    if (max < tm[2]) {
516        max = tm[2];
517        max_idx = 2;
518    }
519#endif
520#ifdef PART2
521    str[3] = "16 r1 i";
522    print_it("des_encrypt_u16_risc1_idx", 3);
523    if (max < tm[3]) {
524        max = tm[3];
525        max_idx = 3;
526    }
527    str[4] = " 4 r2 i";
528    print_it("des_encrypt_u4_risc2_idx ", 4);
529    if (max < tm[4]) {
530        max = tm[4];
531        max_idx = 4;
532    }
533    str[5] = "16 r2 i";
534    print_it("des_encrypt_u16_risc2_idx", 5);
535    if (max < tm[5]) {
536        max = tm[5];
537        max_idx = 5;
538    }
539#endif
540#ifdef PART3
541    str[6] = " 4  c p";
542    print_it("des_encrypt_u4_cisc_ptr  ", 6);
543    if (max < tm[6]) {
544        max = tm[6];
545        max_idx = 6;
546    }
547    str[7] = "16  c p";
548    print_it("des_encrypt_u16_cisc_ptr ", 7);
549    if (max < tm[7]) {
550        max = tm[7];
551        max_idx = 7;
552    }
553    str[8] = " 4 r1 p";
554    print_it("des_encrypt_u4_risc1_ptr ", 8);
555    if (max < tm[8]) {
556        max = tm[8];
557        max_idx = 8;
558    }
559#endif
560#ifdef PART4
561    str[9] = "16 r1 p";
562    print_it("des_encrypt_u16_risc1_ptr", 9);
563    if (max < tm[9]) {
564        max = tm[9];
565        max_idx = 9;
566    }
567    str[10] = " 4 r2 p";
568    print_it("des_encrypt_u4_risc2_ptr ", 10);
569    if (max < tm[10]) {
570        max = tm[10];
571        max_idx = 10;
572    }
573    str[11] = "16 r2 p";
574    print_it("des_encrypt_u16_risc2_ptr", 11);
575    if (max < tm[11]) {
576        max = tm[11];
577        max_idx = 11;
578    }
579#endif
580    printf("options    des ecb/s\n");
581    printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]);
582    d = tm[max_idx];
583    tm[max_idx] = -2.0;
584    max = -1.0;
585    for (;;) {
586        for (i = 0; i < 12; i++) {
587            if (max < tm[i]) {
588                max = tm[i];
589                j = i;
590            }
591        }
592        if (max < 0.0)
593            break;
594        printf("%s %12.2f  %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0);
595        tm[j] = -2.0;
596        max = -1.0;
597    }
598
599    switch (max_idx) {
600    case 0:
601        printf("-DDES_DEFAULT_OPTIONS\n");
602        break;
603    case 1:
604        printf("-DDES_UNROLL\n");
605        break;
606    case 2:
607        printf("-DDES_RISC1\n");
608        break;
609    case 3:
610        printf("-DDES_UNROLL -DDES_RISC1\n");
611        break;
612    case 4:
613        printf("-DDES_RISC2\n");
614        break;
615    case 5:
616        printf("-DDES_UNROLL -DDES_RISC2\n");
617        break;
618    case 6:
619        printf("-DDES_PTR\n");
620        break;
621    case 7:
622        printf("-DDES_UNROLL -DDES_PTR\n");
623        break;
624    case 8:
625        printf("-DDES_RISC1 -DDES_PTR\n");
626        break;
627    case 9:
628        printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
629        break;
630    case 10:
631        printf("-DDES_RISC2 -DDES_PTR\n");
632        break;
633    case 11:
634        printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
635        break;
636    }
637    exit(0);
638#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
639    return (0);
640#endif
641}
642