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