comparison sha1.c @ 0:d7da3b1e1540 libtomcrypt

put back the 0.95 makefile which was inadvertently merged over
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:21:40 +0000
parents
children 6362d3854bb4
comparison
equal deleted inserted replaced
-1:000000000000 0:d7da3b1e1540
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11
12 /* SHA1 code by Tom St Denis */
13 #include "mycrypt.h"
14
15 #ifdef SHA1
16
17 const struct _hash_descriptor sha1_desc =
18 {
19 "sha1",
20 2,
21 20,
22 64,
23 &sha1_init,
24 &sha1_process,
25 &sha1_done,
26 &sha1_test
27 };
28
29 #define F0(x,y,z) (z ^ (x & (y ^ z)))
30 #define F1(x,y,z) (x ^ y ^ z)
31 #define F2(x,y,z) ((x & y) | (z & (x | y)))
32 #define F3(x,y,z) (x ^ y ^ z)
33
34 #ifdef CLEAN_STACK
35 static void _sha1_compress(hash_state *md, unsigned char *buf)
36 #else
37 static void sha1_compress(hash_state *md, unsigned char *buf)
38 #endif
39 {
40 ulong32 a,b,c,d,e,W[80],i;
41
42 /* copy the state into 512-bits into W[0..15] */
43 for (i = 0; i < 16; i++) {
44 LOAD32H(W[i], buf + (4*i));
45 }
46
47 /* copy state */
48 a = md->sha1.state[0];
49 b = md->sha1.state[1];
50 c = md->sha1.state[2];
51 d = md->sha1.state[3];
52 e = md->sha1.state[4];
53
54 /* expand it */
55 for (i = 16; i < 80; i++) {
56 W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
57 }
58
59 /* compress */
60 /* round one */
61 #define FF0(a,b,c,d,e,i) e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);
62 #define FF1(a,b,c,d,e,i) e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);
63 #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
64 #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
65
66 for (i = 0; i < 20; ) {
67 FF0(a,b,c,d,e,i++);
68 FF0(e,a,b,c,d,i++);
69 FF0(d,e,a,b,c,i++);
70 FF0(c,d,e,a,b,i++);
71 FF0(b,c,d,e,a,i++);
72 }
73
74 /* round two */
75 for (; i < 40; ) {
76 FF1(a,b,c,d,e,i++);
77 FF1(e,a,b,c,d,i++);
78 FF1(d,e,a,b,c,i++);
79 FF1(c,d,e,a,b,i++);
80 FF1(b,c,d,e,a,i++);
81 }
82
83 /* round three */
84 for (; i < 60; ) {
85 FF2(a,b,c,d,e,i++);
86 FF2(e,a,b,c,d,i++);
87 FF2(d,e,a,b,c,i++);
88 FF2(c,d,e,a,b,i++);
89 FF2(b,c,d,e,a,i++);
90 }
91
92 /* round four */
93 for (; i < 80; ) {
94 FF3(a,b,c,d,e,i++);
95 FF3(e,a,b,c,d,i++);
96 FF3(d,e,a,b,c,i++);
97 FF3(c,d,e,a,b,i++);
98 FF3(b,c,d,e,a,i++);
99 }
100
101 #undef FF0
102 #undef FF1
103 #undef FF2
104 #undef FF3
105
106 /* store */
107 md->sha1.state[0] = md->sha1.state[0] + a;
108 md->sha1.state[1] = md->sha1.state[1] + b;
109 md->sha1.state[2] = md->sha1.state[2] + c;
110 md->sha1.state[3] = md->sha1.state[3] + d;
111 md->sha1.state[4] = md->sha1.state[4] + e;
112 }
113
114 #ifdef CLEAN_STACK
115 static void sha1_compress(hash_state *md, unsigned char *buf)
116 {
117 _sha1_compress(md, buf);
118 burn_stack(sizeof(ulong32) * 87);
119 }
120 #endif
121
122 void sha1_init(hash_state * md)
123 {
124 _ARGCHK(md != NULL);
125 md->sha1.state[0] = 0x67452301UL;
126 md->sha1.state[1] = 0xefcdab89UL;
127 md->sha1.state[2] = 0x98badcfeUL;
128 md->sha1.state[3] = 0x10325476UL;
129 md->sha1.state[4] = 0xc3d2e1f0UL;
130 md->sha1.curlen = 0;
131 md->sha1.length = 0;
132 }
133
134 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
135
136 int sha1_done(hash_state * md, unsigned char *hash)
137 {
138 int i;
139
140 _ARGCHK(md != NULL);
141 _ARGCHK(hash != NULL);
142
143 if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
144 return CRYPT_INVALID_ARG;
145 }
146
147 /* increase the length of the message */
148 md->sha1.length += md->sha1.curlen * 8;
149
150 /* append the '1' bit */
151 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
152
153 /* if the length is currently above 56 bytes we append zeros
154 * then compress. Then we can fall back to padding zeros and length
155 * encoding like normal.
156 */
157 if (md->sha1.curlen > 56) {
158 while (md->sha1.curlen < 64) {
159 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
160 }
161 sha1_compress(md, md->sha1.buf);
162 md->sha1.curlen = 0;
163 }
164
165 /* pad upto 56 bytes of zeroes */
166 while (md->sha1.curlen < 56) {
167 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
168 }
169
170 /* store length */
171 STORE64H(md->sha1.length, md->sha1.buf+56);
172 sha1_compress(md, md->sha1.buf);
173
174 /* copy output */
175 for (i = 0; i < 5; i++) {
176 STORE32H(md->sha1.state[i], hash+(4*i));
177 }
178 #ifdef CLEAN_STACK
179 zeromem(md, sizeof(hash_state));
180 #endif
181 return CRYPT_OK;
182 }
183
184 int sha1_test(void)
185 {
186 #ifndef LTC_TEST
187 return CRYPT_NOP;
188 #else
189 static const struct {
190 char *msg;
191 unsigned char hash[20];
192 } tests[] = {
193 { "abc",
194 { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
195 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
196 0x9c, 0xd0, 0xd8, 0x9d }
197 },
198 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
199 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
200 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
201 0xE5, 0x46, 0x70, 0xF1 }
202 }
203 };
204
205 int i;
206 unsigned char tmp[20];
207 hash_state md;
208
209 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
210 sha1_init(&md);
211 sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
212 sha1_done(&md, tmp);
213 if (memcmp(tmp, tests[i].hash, 20) != 0) {
214 return CRYPT_FAIL_TESTVECTOR;
215 }
216 }
217 return CRYPT_OK;
218 #endif
219 }
220
221 #endif
222
223