modernc.org/ccgo/v3@v3.16.14/lib/testdata/CompCert-3.6/test/c/sha1.c (about) 1 /* SHA-1 cryptographic hash function */ 2 /* Ref: Handbook of Applied Cryptography, section 9.4.2, algorithm 9.53 */ 3 4 #include <string.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 8 typedef unsigned int u32; 9 10 struct SHA1Context { 11 u32 state[5]; 12 u32 length[2]; 13 int numbytes; 14 unsigned char buffer[64]; 15 }; 16 17 #define rol1(x) (((x) << 1) | ((x) >> 31)) 18 #define rol5(x) (((x) << 5) | ((x) >> 27)) 19 #define rol30(x) (((x) << 30) | ((x) >> 2)) 20 21 static int arch_big_endian; 22 23 static void SHA1_copy_and_swap(void * src, void * dst, int numwords) 24 { 25 if (arch_big_endian) { 26 memcpy(dst, src, numwords * sizeof(u32)); 27 } else { 28 unsigned char * s, * d; 29 unsigned char a, b; 30 for (s = src, d = dst; numwords > 0; s += 4, d += 4, numwords--) { 31 a = s[0]; 32 b = s[1]; 33 d[0] = s[3]; 34 d[1] = s[2]; 35 d[2] = b; 36 d[3] = a; 37 } 38 } 39 } 40 41 #define F(x,y,z) ( z ^ (x & (y ^ z) ) ) 42 #define G(x,y,z) ( (x & y) | (z & (x | y) ) ) 43 #define H(x,y,z) ( x ^ y ^ z ) 44 45 #define Y1 0x5A827999U 46 #define Y2 0x6ED9EBA1U 47 #define Y3 0x8F1BBCDCU 48 #define Y4 0xCA62C1D6U 49 50 static void SHA1_transform(struct SHA1Context * ctx) 51 { 52 int i; 53 register u32 a, b, c, d, e, t; 54 u32 data[80]; 55 56 /* Convert buffer data to 16 big-endian integers */ 57 SHA1_copy_and_swap(ctx->buffer, data, 16); 58 59 /* Expand into 80 integers */ 60 for (i = 16; i < 80; i++) { 61 t = data[i-3] ^ data[i-8] ^ data[i-14] ^ data[i-16]; 62 data[i] = rol1(t); 63 } 64 65 /* Initialize working variables */ 66 a = ctx->state[0]; 67 b = ctx->state[1]; 68 c = ctx->state[2]; 69 d = ctx->state[3]; 70 e = ctx->state[4]; 71 72 /* Perform rounds */ 73 for (i = 0; i < 20; i++) { 74 t = F(b, c, d) + Y1 + rol5(a) + e + data[i]; 75 e = d; d = c; c = rol30(b); b = a; a = t; 76 } 77 for (/*nothing*/; i < 40; i++) { 78 t = H(b, c, d) + Y2 + rol5(a) + e + data[i]; 79 e = d; d = c; c = rol30(b); b = a; a = t; 80 } 81 for (/*nothing*/; i < 60; i++) { 82 t = G(b, c, d) + Y3 + rol5(a) + e + data[i]; 83 e = d; d = c; c = rol30(b); b = a; a = t; 84 } 85 for (/*nothing*/; i < 80; i++) { 86 t = H(b, c, d) + Y4 + rol5(a) + e + data[i]; 87 e = d; d = c; c = rol30(b); b = a; a = t; 88 } 89 90 /* Update chaining values */ 91 ctx->state[0] += a; 92 ctx->state[1] += b; 93 ctx->state[2] += c; 94 ctx->state[3] += d; 95 ctx->state[4] += e; 96 } 97 98 void SHA1_init(struct SHA1Context * ctx) 99 { 100 ctx->state[0] = 0x67452301U; 101 ctx->state[1] = 0xEFCDAB89U; 102 ctx->state[2] = 0x98BADCFEU; 103 ctx->state[3] = 0x10325476U; 104 ctx->state[4] = 0xC3D2E1F0U; 105 ctx->numbytes = 0; 106 ctx->length[0] = 0; 107 ctx->length[1] = 0; 108 } 109 110 void SHA1_add_data(struct SHA1Context * ctx, unsigned char * data, 111 unsigned long len) 112 { 113 u32 t; 114 115 /* Update length */ 116 t = ctx->length[1]; 117 if ((ctx->length[1] = t + (u32) (len << 3)) < t) 118 ctx->length[0]++; /* carry from low 32 bits to high 32 bits */ 119 ctx->length[0] += (u32) (len >> 29); 120 121 /* If data was left in buffer, pad it with fresh data and munge block */ 122 if (ctx->numbytes != 0) { 123 t = 64 - ctx->numbytes; 124 if (len < t) { 125 memcpy(ctx->buffer + ctx->numbytes, data, len); 126 ctx->numbytes += len; 127 return; 128 } 129 memcpy(ctx->buffer + ctx->numbytes, data, t); 130 SHA1_transform(ctx); 131 data += t; 132 len -= t; 133 } 134 /* Munge data in 64-byte chunks */ 135 while (len >= 64) { 136 memcpy(ctx->buffer, data, 64); 137 SHA1_transform(ctx); 138 data += 64; 139 len -= 64; 140 } 141 /* Save remaining data */ 142 memcpy(ctx->buffer, data, len); 143 ctx->numbytes = len; 144 } 145 146 void SHA1_finish(struct SHA1Context * ctx, unsigned char output[20]) 147 { 148 int i = ctx->numbytes; 149 150 /* Set first char of padding to 0x80. There is always room. */ 151 ctx->buffer[i++] = 0x80; 152 /* If we do not have room for the length (8 bytes), pad to 64 bytes 153 with zeroes and munge the data block */ 154 if (i > 56) { 155 memset(ctx->buffer + i, 0, 64 - i); 156 SHA1_transform(ctx); 157 i = 0; 158 } 159 /* Pad to byte 56 with zeroes */ 160 memset(ctx->buffer + i, 0, 56 - i); 161 /* Add length in big-endian */ 162 SHA1_copy_and_swap(ctx->length, ctx->buffer + 56, 2); 163 /* Munge the final block */ 164 SHA1_transform(ctx); 165 /* Final hash value is in ctx->state modulo big-endian conversion */ 166 SHA1_copy_and_swap(ctx->state, output, 5); 167 } 168 169 /* Test harness */ 170 171 static void do_test(unsigned char * txt, unsigned char * expected_output) 172 { 173 struct SHA1Context ctx; 174 unsigned char output[20]; 175 int ok; 176 177 SHA1_init(&ctx); 178 SHA1_add_data(&ctx, txt, strlen((char *) txt)); 179 SHA1_finish(&ctx, output); 180 ok = memcmp(output, expected_output, 20) == 0; 181 printf("Test `%s': %s\n", 182 (char *) txt, (ok ? "passed" : "FAILED")); 183 } 184 185 /* Test vectors: 186 * 187 * "abc" 188 * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D 189 * 190 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 191 * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1 192 */ 193 194 unsigned char test_input_1[] = "abc"; 195 196 unsigned char test_output_1[20] = 197 { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E , 198 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }; 199 200 unsigned char test_input_2[] = 201 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 202 203 unsigned char test_output_2[20] = 204 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 205 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }; 206 207 208 static void do_bench(int nblocks) 209 { 210 struct SHA1Context ctx; 211 unsigned char output[20]; 212 unsigned char data[64]; 213 int i; 214 215 for (i = 0; i < 64; i++) data[i] = i; 216 SHA1_init(&ctx); 217 for (; nblocks > 0; nblocks--) 218 SHA1_add_data(&ctx, data, 64); 219 SHA1_finish(&ctx, output); 220 } 221 222 int main(int argc, char ** argv) 223 { 224 /* Determine endianness */ 225 union { int i; unsigned char b[4]; } u; 226 u.i = 0x12345678; 227 switch (u.b[0]) { 228 case 0x12: arch_big_endian = 1; break; 229 case 0x78: arch_big_endian = 0; break; 230 default: printf("Cannot determine endianness\n"); return 2; 231 } 232 do_test(test_input_1, test_output_1); 233 do_test(test_input_2, test_output_2); 234 do_bench(200000); 235 return 0; 236 }