bf_opts.c revision 296465
1/* crypto/bf/bf_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
70#include <openssl/e_os2.h>
71#include OPENSSL_UNISTD_IO
72OPENSSL_DECLARE_EXIT
73#ifndef OPENSSL_SYS_NETWARE
74# include <signal.h>
75#endif
76#ifndef _IRIX
77# include <time.h>
78#endif
79#ifdef TIMES
80# include <sys/types.h>
81# include <sys/times.h>
82#endif
83    /*
84     * Depending on the VMS version, the tms structure is perhaps defined.
85     * The __TMS macro will show if it was.  If it wasn't defined, we should
86     * undefine TIMES, since that tells the rest of the program how things
87     * should be handled.  -- Richard Levitte
88     */
89#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
90# undef TIMES
91#endif
92#ifndef TIMES
93# include <sys/timeb.h>
94#endif
95#if defined(sun) || defined(__ultrix)
96# define _POSIX_SOURCE
97# include <limits.h>
98# include <sys/param.h>
99#endif
100#include <openssl/blowfish.h>
101#define BF_DEFAULT_OPTIONS
102#undef BF_ENC
103#define BF_encrypt  BF_encrypt_normal
104#undef HEADER_BF_LOCL_H
105#include "bf_enc.c"
106#define BF_PTR
107#undef BF_PTR2
108#undef BF_ENC
109#undef BF_encrypt
110#define BF_encrypt  BF_encrypt_ptr
111#undef HEADER_BF_LOCL_H
112#include "bf_enc.c"
113#undef BF_PTR
114#define BF_PTR2
115#undef BF_ENC
116#undef BF_encrypt
117#define BF_encrypt  BF_encrypt_ptr2
118#undef HEADER_BF_LOCL_H
119#include "bf_enc.c"
120/* The following if from times(3) man page.  It may need to be changed */
121#ifndef HZ
122# ifndef CLK_TCK
123#  ifndef _BSD_CLK_TCK_         /* FreeBSD fix */
124#   define HZ   100.0
125#  else                         /* _BSD_CLK_TCK_ */
126#   define HZ ((double)_BSD_CLK_TCK_)
127#  endif
128# else                          /* CLK_TCK */
129#  define HZ ((double)CLK_TCK)
130# endif
131#endif
132#define BUFSIZE ((long)1024)
133long run = 0;
134
135double Time_F(int s);
136#ifdef SIGALRM
137# if defined(__STDC__) || defined(sgi)
138#  define SIGRETTYPE void
139# else
140#  define SIGRETTYPE int
141# endif
142
143SIGRETTYPE sig_done(int sig);
144SIGRETTYPE sig_done(int sig)
145{
146    signal(SIGALRM, sig_done);
147    run = 0;
148# ifdef LINT
149    sig = sig;
150# endif
151}
152#endif
153
154#define START   0
155#define STOP    1
156
157double Time_F(int s)
158{
159    double ret;
160#ifdef TIMES
161    static struct tms tstart, tend;
162
163    if (s == START) {
164        times(&tstart);
165        return (0);
166    } else {
167        times(&tend);
168        ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ;
169        return ((ret == 0.0) ? 1e-6 : ret);
170    }
171#else                           /* !times() */
172    static struct timeb tstart, tend;
173    long i;
174
175    if (s == START) {
176        ftime(&tstart);
177        return (0);
178    } else {
179        ftime(&tend);
180        i = (long)tend.millitm - (long)tstart.millitm;
181        ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0;
182        return ((ret == 0.0) ? 1e-6 : ret);
183    }
184#endif
185}
186
187#ifdef SIGALRM
188# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
189#else
190# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
191#endif
192
193#define time_it(func,name,index) \
194        print_name(name); \
195        Time_F(START); \
196        for (count=0,run=1; COND(cb); count+=4) \
197                { \
198                unsigned long d[2]; \
199                func(d,&sch); \
200                func(d,&sch); \
201                func(d,&sch); \
202                func(d,&sch); \
203                } \
204        tm[index]=Time_F(STOP); \
205        fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
206        tm[index]=((double)COUNT(cb))/tm[index];
207
208#define print_it(name,index) \
209        fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
210                tm[index]*8,1.0e6/tm[index]);
211
212int main(int argc, char **argv)
213{
214    long count;
215    static unsigned char buf[BUFSIZE];
216    static char key[16] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
217        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0
218    };
219    BF_KEY sch;
220    double d, tm[16], max = 0;
221    int rank[16];
222    char *str[16];
223    int max_idx = 0, i, num = 0, j;
224#ifndef SIGALARM
225    long ca, cb, cc, cd, ce;
226#endif
227
228    for (i = 0; i < 12; i++) {
229        tm[i] = 0.0;
230        rank[i] = 0;
231    }
232
233#ifndef TIMES
234    fprintf(stderr, "To get the most accurate results, try to run this\n");
235    fprintf(stderr, "program when this computer is idle.\n");
236#endif
237
238    BF_set_key(&sch, 16, key);
239
240#ifndef SIGALRM
241    fprintf(stderr, "First we calculate the approximate speed ...\n");
242    count = 10;
243    do {
244        long i;
245        unsigned long data[2];
246
247        count *= 2;
248        Time_F(START);
249        for (i = count; i; i--)
250            BF_encrypt(data, &sch);
251        d = Time_F(STOP);
252    } while (d < 3.0);
253    ca = count;
254    cb = count * 3;
255    cc = count * 3 * 8 / BUFSIZE + 1;
256    cd = count * 8 / BUFSIZE + 1;
257
258    ce = count / 20 + 1;
259# define COND(d) (count != (d))
260# define COUNT(d) (d)
261#else
262# define COND(c) (run)
263# define COUNT(d) (count)
264    signal(SIGALRM, sig_done);
265    alarm(10);
266#endif
267
268    time_it(BF_encrypt_normal, "BF_encrypt_normal ", 0);
269    time_it(BF_encrypt_ptr, "BF_encrypt_ptr    ", 1);
270    time_it(BF_encrypt_ptr2, "BF_encrypt_ptr2   ", 2);
271    num += 3;
272
273    str[0] = "<nothing>";
274    print_it("BF_encrypt_normal ", 0);
275    max = tm[0];
276    max_idx = 0;
277    str[1] = "ptr      ";
278    print_it("BF_encrypt_ptr ", 1);
279    if (max < tm[1]) {
280        max = tm[1];
281        max_idx = 1;
282    }
283    str[2] = "ptr2     ";
284    print_it("BF_encrypt_ptr2 ", 2);
285    if (max < tm[2]) {
286        max = tm[2];
287        max_idx = 2;
288    }
289
290    printf("options    BF ecb/s\n");
291    printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]);
292    d = tm[max_idx];
293    tm[max_idx] = -2.0;
294    max = -1.0;
295    for (;;) {
296        for (i = 0; i < 3; i++) {
297            if (max < tm[i]) {
298                max = tm[i];
299                j = i;
300            }
301        }
302        if (max < 0.0)
303            break;
304        printf("%s %12.2f  %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0);
305        tm[j] = -2.0;
306        max = -1.0;
307    }
308
309    switch (max_idx) {
310    case 0:
311        printf("-DBF_DEFAULT_OPTIONS\n");
312        break;
313    case 1:
314        printf("-DBF_PTR\n");
315        break;
316    case 2:
317        printf("-DBF_PTR2\n");
318        break;
319    }
320    exit(0);
321#if defined(LINT) || defined(OPENSSL_SYS_MSDOS)
322    return (0);
323#endif
324}
325