1 /*
2  * FILE:	sha2speed.c
3  * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
4  *
5  * Copyright (c) 2000-2001, Aaron D. Gifford
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holder nor the names of contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: sha2speed.c,v 1.1 2001/11/08 00:02:23 adg Exp adg $
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/time.h>
39 
40 #include "sha2.h"
41 
42 #define BUFSIZE	16384
43 
usage(char * prog)44 void usage(char *prog) {
45 	fprintf(stderr, "Usage:\t%s [<num-of-bytes>] [<num-of-loops>] [<fill-byte>]\n", prog);
46 	exit(-1);
47 }
48 
printspeed(char * caption,unsigned long bytes,double time)49 void printspeed(char *caption, unsigned long bytes, double time) {
50 	if (bytes / 1073741824UL > 0) {
51                 printf("%s %.4f sec (%.3f GBps)\n", caption, time, (double)bytes/1073741824UL/time);
52         } else if (bytes / 1048576 > 0) {
53                 printf("%s %.4f (%.3f MBps)\n", caption, time, (double)bytes/1048576/time);
54         } else if (bytes / 1024 > 0) {
55                 printf("%s %.4f (%.3f KBps)\n", caption, time, (double)bytes/1024/time);
56         } else {
57 		printf("%s %.4f (%f Bps)\n", caption, time, (double)bytes/time);
58 	}
59 }
60 
61 
main(int argc,char ** argv)62 int main(int argc, char **argv) {
63 	SHA256_CTX	c256;
64 	SHA384_CTX	c384;
65 	SHA512_CTX	c512;
66 	char		buf[BUFSIZE];
67 	char		md[SHA512_DIGEST_STRING_LENGTH];
68 	int		bytes, blocks, rep, i, j;
69 	struct timeval	start, end;
70 	double		t, ave256, ave384, ave512;
71 	double		best256, best384, best512;
72 
73 	if (argc > 4) {
74 		usage(argv[0]);
75 	}
76 
77 	/* Default to 1024 16K blocks (16 MB) */
78 	bytes = 1024 * 1024 * 16;
79 	if (argc > 1) {
80 		blocks = atoi(argv[1]);
81 	}
82 	blocks = bytes / BUFSIZE;
83 
84 	/* Default to 10 repetitions */
85 	rep = 10;
86 	if (argc > 2) {
87 		rep = atoi(argv[2]);
88 	}
89 
90 	/* Set up the input data */
91 	if (argc > 3) {
92 		memset(buf, atoi(argv[2]), BUFSIZE);
93 	} else {
94 		memset(buf, 0xb7, BUFSIZE);
95 	}
96 
97 	ave256 = ave384 = ave512 = 0;
98 	best256 = best384 = best512 = 100000;
99 	for (i = 0; i < rep; i++) {
100 		SHA256_Init(&c256);
101 		SHA384_Init(&c384);
102 		SHA512_Init(&c512);
103 
104 		gettimeofday(&start, (struct timezone*)0);
105 		for (j = 0; j < blocks; j++) {
106 			SHA256_Update(&c256, (unsigned char*)buf, BUFSIZE);
107 		}
108 		if (bytes % BUFSIZE) {
109 			SHA256_Update(&c256, (unsigned char*)buf, bytes % BUFSIZE);
110 		}
111 		SHA256_End(&c256, md);
112 		gettimeofday(&end, (struct timezone*)0);
113 		t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
114 		ave256 += t;
115 		if (t < best256) {
116 			best256 = t;
117 		}
118 		printf("SHA-256[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave256/(i+1), best256, md);
119 
120 		gettimeofday(&start, (struct timezone*)0);
121 		for (j = 0; j < blocks; j++) {
122 			SHA384_Update(&c384, (unsigned char*)buf, BUFSIZE);
123 		}
124 		if (bytes % BUFSIZE) {
125 			SHA384_Update(&c384, (unsigned char*)buf, bytes % BUFSIZE);
126 		}
127 		SHA384_End(&c384, md);
128 		gettimeofday(&end, (struct timezone*)0);
129 		t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
130 		ave384 += t;
131 		if (t < best384) {
132 			best384 = t;
133 		}
134 		printf("SHA-384[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave384/(i+1), best384, md);
135 
136 		gettimeofday(&start, (struct timezone*)0);
137 		for (j = 0; j < blocks; j++) {
138 			SHA512_Update(&c512, (unsigned char*)buf, BUFSIZE);
139 		}
140 		if (bytes % BUFSIZE) {
141 			SHA512_Update(&c512, (unsigned char*)buf, bytes % BUFSIZE);
142 		}
143 		SHA512_End(&c512, md);
144 		gettimeofday(&end, (struct timezone*)0);
145 		t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
146 		ave512 += t;
147 		if (t < best512) {
148 			best512 = t;
149 		}
150 		printf("SHA-512[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave512/(i+1), best512, md);
151 	}
152 	ave256 /= rep;
153 	ave384 /= rep;
154 	ave512 /= rep;
155 	printf("\nTEST RESULTS SUMMARY:\nTEST REPETITIONS: %d\n", rep);
156 	if (bytes / 1073741824UL > 0) {
157 		printf("TEST SET SIZE: %.3f GB\n", (double)bytes/1073741824UL);
158 	} else if (bytes / 1048576 > 0) {
159 		printf("TEST SET SIZE: %.3f MB\n", (double)bytes/1048576);
160 	} else if (bytes /1024 > 0) {
161 		printf("TEST SET SIZE: %.3f KB\n", (double)bytes/1024);
162 	} else {
163 		printf("TEST SET SIZE: %d B\n", bytes);
164 	}
165 	printspeed("SHA-256 average:", bytes, ave256);
166 	printspeed("SHA-256 best:   ", bytes, best256);
167 	printspeed("SHA-384 average:", bytes, ave384);
168 	printspeed("SHA-384 best:   ", bytes, best384);
169 	printspeed("SHA-512 average:", bytes, ave512);
170 	printspeed("SHA-512 best:   ", bytes, best512);
171 
172 	return 1;
173 }
174 
175