├── .gitignore ├── README.md ├── sha1.c ├── sha1.h └── tests ├── sha1_test.c └── sha1_test.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | /tests/build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

SHA-1 Hashing

2 | 3 |

4 | discord 5 | twitter 6 |

7 | 8 | A simple SHA-1 hashing implementation. Usage: 9 | 10 | unsigned char digest[SHA1_SIZE]; 11 | sha1_context ctx; 12 | sha1_init(&ctx); 13 | { 14 | sha1_update(&ctx, src, sz); 15 | } 16 | sha1_finalize(&ctx, digest); 17 | 18 | The above code is the literal implementation of `sha1()` which is a high level helper for hashing 19 | data of a known size: 20 | 21 | unsigned char hash[SHA1_SIZE]; 22 | sha1(hash, data, dataSize); 23 | 24 | Use `sha1_format()` to format the digest as a hex string. The capacity of the output buffer needs to 25 | be at least `SHA1_SIZE_FORMATTED` bytes. 26 | 27 | This library does not perform any memory allocations and does not use anything from the standard 28 | library except for `size_t` and `NULL`, both of which are drawn in from stddef.h. No other standard 29 | headers are included. 30 | 31 | There is no need to link to anything with this library. You can use SHA1_IMPLEMENTATION to define 32 | the implementation section, or you can use sha1.c if you prefer a traditional header/source pair. 33 | 34 | This implements both methods defined in RFC 3174. Method 1 will be used by default. If you want to 35 | use Method 2, define `SHA1_USE_RFC_METHOD_2` at compile time. 36 | 37 | #define SHA1_USE_RFC_METHOD_2 38 | #define SHA1_IMPLEMENTATION 39 | #include "sha1.h" 40 | 41 | No effort has been made to optimize this beyond the algorithms described in RGC 3174. If you're 42 | looking for the fastest SHA-1 implementation you'll need to look elsewhere. An optimized 43 | implementation may come later. -------------------------------------------------------------------------------- /sha1.c: -------------------------------------------------------------------------------- 1 | #define SHA1_IMPLEMENTATION 2 | #include "sha1.h" 3 | -------------------------------------------------------------------------------- /sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | SHA-1 hashing. Choice of public domain or MIT-0. See license statements at the end of this file. 3 | 4 | David Reid - mackron@gmail.com 5 | */ 6 | 7 | /* 8 | A simple SHA-1 hashing implementation. Usage: 9 | 10 | unsigned char digest[SHA1_SIZE]; 11 | sha1_context ctx; 12 | sha1_init(&ctx); 13 | { 14 | sha1_update(&ctx, src, sz); 15 | } 16 | sha1_finalize(&ctx, digest); 17 | 18 | The above code is the literal implementation of `sha1()` which is a high level helper for hashing 19 | data of a known size: 20 | 21 | unsigned char hash[SHA1_SIZE]; 22 | sha1(hash, data, dataSize); 23 | 24 | Use `sha1_format()` to format the digest as a hex string. The capacity of the output buffer needs to 25 | be at least `SHA1_SIZE_FORMATTED` bytes. 26 | 27 | This library does not perform any memory allocations and does not use anything from the standard 28 | library except for `size_t` and `NULL`, both of which are drawn in from stddef.h. No other standard 29 | headers are included. 30 | 31 | There is no need to link to anything with this library. You can use SHA1_IMPLEMENTATION to define 32 | the implementation section, or you can use sha1.c if you prefer a traditional header/source pair. 33 | 34 | This implements both methods defined in RFC 3174. Method 1 will be used by default. If you want to 35 | use Method 2, define `SHA1_USE_RFC_METHOD_2` at compile time. 36 | 37 | #define SHA1_USE_RFC_METHOD_2 38 | #define SHA1_IMPLEMENTATION 39 | #include "sha1.h" 40 | 41 | No effort has been made to optimize this beyond the algorithms described in RGC 3174. If you're 42 | looking for the fastest SHA-1 implementation you'll need to look elsewhere. An optimized 43 | implementation may come later. 44 | */ 45 | #ifndef sha1_h 46 | #define sha1_h 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | #include /* For size_t and NULL. */ 53 | 54 | #if defined(_MSC_VER) 55 | typedef unsigned __int64 sha1_uint64; 56 | #else 57 | typedef unsigned long long sha1_uint64; 58 | #endif 59 | 60 | #if !defined(SHA1_API) 61 | #define SHA1_API 62 | #endif 63 | 64 | #define SHA1_SIZE 20 65 | #define SHA1_SIZE_FORMATTED 41 66 | 67 | typedef struct 68 | { 69 | unsigned int h[5]; 70 | sha1_uint64 sz; 71 | unsigned char cache[64]; 72 | unsigned int cacheLen; 73 | } sha1_context; 74 | 75 | SHA1_API void sha1_init(sha1_context* ctx); 76 | SHA1_API void sha1_update(sha1_context* ctx, const void* src, size_t sz); 77 | SHA1_API void sha1_finalize(sha1_context* ctx, unsigned char* digest); 78 | SHA1_API void sha1(unsigned char* digest, const void* src, size_t sz); 79 | SHA1_API void sha1_format(char* dst, size_t dstCap, const unsigned char* hash); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | #endif /* sha1_h */ 85 | 86 | #if defined(SHA1_IMPLEMENTATION) 87 | #ifndef sha1_c 88 | #define sha1_c 89 | 90 | #define SHA1_ALGORITHM_RFC_METHOD_1 1 91 | #define SHA1_ALGORITHM_RFC_METHOD_2 2 92 | #define SHA1_ALGORITHM_DEFAULT SHA1_ALGORITHM_RFC_METHOD_1 93 | 94 | # if defined(SHA1_USE_RFC_METHOD_1) 95 | #define SHA1_ALGORITHM SHA1_ALGORITHM_RFC_METHOD_1 96 | #elif defined(SHA1_USE_RFC_METHOD_2) 97 | #define SHA1_ALGORITHM SHA1_ALGORITHM_RFC_METHOD_2 98 | #else 99 | #define SHA1_ALGORITHM SHA1_ALGORITHM_DEFAULT 100 | #endif 101 | 102 | 103 | static void sha1_zero_memory(void* p, size_t sz) 104 | { 105 | size_t i; 106 | for (i = 0; i < sz; i += 1) { 107 | ((unsigned char*)p)[i] = 0; 108 | } 109 | } 110 | 111 | static void sha1_copy_memory(void* dst, const void* src, size_t sz) 112 | { 113 | size_t i; 114 | for (i = 0; i < sz; i += 1) { 115 | ((unsigned char*)dst)[i] = ((unsigned char*)src)[i]; 116 | } 117 | } 118 | 119 | 120 | #define SHA1_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 121 | 122 | #define SHA1_F00(b, c, d) (((b) & (c)) | ((~(b)) & (d))) /* (B AND C) OR ((NOT B) AND D) */ 123 | #define SHA1_F20(b, c, d) ((b) ^ (c) ^ (d)) /* B XOR C XOR D */ 124 | #define SHA1_F40(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) /* (B AND C) OR (B AND D) OR (C AND D) */ 125 | #define SHA1_F60(b, c, d) ((b) ^ (c) ^ (d)) /* B XOR C XOR D */ 126 | 127 | /* 128 | This is the main SHA-1 function. Everything is processed in blocks of 64 bytes. 129 | */ 130 | static void sha1_update_block(sha1_context* ctx, const unsigned char* src) 131 | { 132 | size_t i; 133 | unsigned int w[80]; 134 | unsigned int a, b, c, d, e; 135 | unsigned int temp; 136 | 137 | /* assert(ctx != NULL); */ 138 | /* assert(src != NULL); */ 139 | 140 | for (i = 0; i < 16; i += 1) { 141 | w[i] = (src[i*4 + 0] << 24); 142 | w[i] |= (src[i*4 + 1] << 16); 143 | w[i] |= (src[i*4 + 2] << 8); 144 | w[i] |= (src[i*4 + 3] << 0); 145 | } 146 | 147 | a = ctx->h[0]; 148 | b = ctx->h[1]; 149 | c = ctx->h[2]; 150 | d = ctx->h[3]; 151 | e = ctx->h[4]; 152 | 153 | #if SHA1_ALGORITHM == SHA1_ALGORITHM_RFC_METHOD_1 154 | { 155 | for (i = 16; i < 80; i += 1) { 156 | w[i] = SHA1_ROTATE_LEFT((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); 157 | } 158 | 159 | for (i = 0; i < 20; i += 1) { 160 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F00(b, c, d) + e + w[i] + 0x5A827999; 161 | e = d; 162 | d = c; 163 | c = SHA1_ROTATE_LEFT(b, 30); 164 | b = a; 165 | a = temp; 166 | } 167 | 168 | for (i = 20; i < 40; i += 1) { 169 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F20(b, c, d) + e + w[i] + 0x6ED9EBA1; 170 | e = d; 171 | d = c; 172 | c = SHA1_ROTATE_LEFT(b, 30); 173 | b = a; 174 | a = temp; 175 | } 176 | 177 | for (i = 40; i < 60; i += 1) { 178 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F40(b, c, d) + e + w[i] + 0x8F1BBCDC; 179 | e = d; 180 | d = c; 181 | c = SHA1_ROTATE_LEFT(b, 30); 182 | b = a; 183 | a = temp; 184 | } 185 | 186 | for (i = 60; i < 80; i += 1) { 187 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F60(b, c, d) + e + w[i] + 0xCA62C1D6; 188 | e = d; 189 | d = c; 190 | c = SHA1_ROTATE_LEFT(b, 30); 191 | b = a; 192 | a = temp; 193 | } 194 | } 195 | #endif 196 | 197 | #if SHA1_ALGORITHM == SHA1_ALGORITHM_RFC_METHOD_2 198 | { 199 | unsigned int mask = 0x0000000F; 200 | unsigned int s; 201 | 202 | for (i = 0; i < 16; i += 1) { 203 | s = i & mask; 204 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F00(b, c, d) + e + w[s] + 0x5A827999; 205 | e = d; 206 | d = c; 207 | c = SHA1_ROTATE_LEFT(b, 30); 208 | b = a; 209 | a = temp; 210 | } 211 | 212 | for (i = 16; i < 20; i += 1) { 213 | s = i & mask; 214 | w[s] = SHA1_ROTATE_LEFT(w[(s + 13) & mask] ^ w[(s + 8) & mask] ^ w[(s + 2) & mask] ^ w[s], 1); 215 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F00(b, c, d) + e + w[s] + 0x5A827999; 216 | e = d; 217 | d = c; 218 | c = SHA1_ROTATE_LEFT(b, 30); 219 | b = a; 220 | a = temp; 221 | } 222 | 223 | for (i = 20; i < 40; i += 1) { 224 | s = i & mask; 225 | w[s] = SHA1_ROTATE_LEFT(w[(s + 13) & mask] ^ w[(s + 8) & mask] ^ w[(s + 2) & mask] ^ w[s], 1); 226 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F20(b, c, d) + e + w[s] + 0x6ED9EBA1; 227 | e = d; 228 | d = c; 229 | c = SHA1_ROTATE_LEFT(b, 30); 230 | b = a; 231 | a = temp; 232 | } 233 | 234 | for (i = 40; i < 60; i += 1) { 235 | s = i & mask; 236 | w[s] = SHA1_ROTATE_LEFT(w[(s + 13) & mask] ^ w[(s + 8) & mask] ^ w[(s + 2) & mask] ^ w[s], 1); 237 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F40(b, c, d) + e + w[s] + 0x8F1BBCDC; 238 | e = d; 239 | d = c; 240 | c = SHA1_ROTATE_LEFT(b, 30); 241 | b = a; 242 | a = temp; 243 | } 244 | 245 | for (i = 60; i < 80; i += 1) { 246 | s = i & mask; 247 | w[s] = SHA1_ROTATE_LEFT(w[(s + 13) & mask] ^ w[(s + 8) & mask] ^ w[(s + 2) & mask] ^ w[s], 1); 248 | temp = SHA1_ROTATE_LEFT(a, 5) + SHA1_F60(b, c, d) + e + w[s] + 0xCA62C1D6; 249 | e = d; 250 | d = c; 251 | c = SHA1_ROTATE_LEFT(b, 30); 252 | b = a; 253 | a = temp; 254 | } 255 | } 256 | #endif 257 | 258 | ctx->h[0] += a; 259 | ctx->h[1] += b; 260 | ctx->h[2] += c; 261 | ctx->h[3] += d; 262 | ctx->h[4] += e; 263 | 264 | /* We'll only ever be calling this if the context's cache is full. At this point the cache will also be empty. */ 265 | ctx->cacheLen = 0; 266 | } 267 | 268 | SHA1_API void sha1_init(sha1_context* ctx) 269 | { 270 | if (ctx == NULL) { 271 | return; 272 | } 273 | 274 | sha1_zero_memory(ctx, sizeof(*ctx)); 275 | 276 | ctx->h[0] = 0x67452301; 277 | ctx->h[1] = 0xEFCDAB89; 278 | ctx->h[2] = 0x98BADCFE; 279 | ctx->h[3] = 0x10325476; 280 | ctx->h[4] = 0xC3D2E1F0; 281 | } 282 | 283 | SHA1_API void sha1_update(sha1_context* ctx, const void* src, size_t sz) 284 | { 285 | const unsigned char* bytes = (const unsigned char*)src; 286 | size_t totalBytesProcessed = 0; 287 | 288 | if (ctx == NULL || (src == NULL && sz > 0)) { 289 | return; 290 | } 291 | 292 | /* Keep processing until all data has been exhausted. */ 293 | while (totalBytesProcessed < sz) { 294 | /* Optimization. Bypass the cache if there's nothing in it and the number of bytes remaining to process is larger than 64. */ 295 | size_t bytesRemainingToProcess = sz - totalBytesProcessed; 296 | if (ctx->cacheLen == 0 && bytesRemainingToProcess > sizeof(ctx->cache)) { 297 | /* Fast path. Bypass the cache and just process directly. */ 298 | sha1_update_block(ctx, bytes + totalBytesProcessed); 299 | totalBytesProcessed += sizeof(ctx->cache); 300 | } else { 301 | /* Slow path. Need to store in the cache. */ 302 | size_t cacheRemaining = sizeof(ctx->cache) - ctx->cacheLen; 303 | if (cacheRemaining > 0) { 304 | /* There's still some room left in the cache. Write as much data to it as we can. */ 305 | size_t bytesToProcess = bytesRemainingToProcess; 306 | if (bytesToProcess > cacheRemaining) { 307 | bytesToProcess = cacheRemaining; 308 | } 309 | 310 | sha1_copy_memory(ctx->cache + ctx->cacheLen, bytes + totalBytesProcessed, bytesToProcess); 311 | ctx->cacheLen += (unsigned int)bytesToProcess; /* Safe cast. bytesToProcess will always be <= sizeof(ctx->cache) which is 64. */ 312 | totalBytesProcessed += bytesToProcess; 313 | 314 | /* Update the number of bytes remaining in the cache so we can use it later. */ 315 | cacheRemaining = sizeof(ctx->cache) - ctx->cacheLen; 316 | } 317 | 318 | /* If the cache is full, get it processed. */ 319 | if (cacheRemaining == 0) { 320 | sha1_update_block(ctx, ctx->cache); 321 | } 322 | } 323 | } 324 | 325 | ctx->sz += sz; 326 | } 327 | 328 | SHA1_API void sha1_finalize(sha1_context* ctx, unsigned char* digest) 329 | { 330 | size_t cacheRemaining; 331 | unsigned int szLo; 332 | unsigned int szHi; 333 | 334 | if (digest == NULL) { 335 | return; 336 | } 337 | 338 | if (ctx == NULL) { 339 | sha1_zero_memory(digest, SHA1_SIZE); 340 | return; 341 | } 342 | 343 | /* 344 | Padding must be applied. First thing to do is clear the cache if there's no room for at least 345 | one byte. This should never happen, but leaving this logic here for safety. 346 | */ 347 | cacheRemaining = sizeof(ctx->cache) - ctx->cacheLen; 348 | if (cacheRemaining == 0) { 349 | sha1_update_block(ctx, ctx->cache); 350 | } 351 | 352 | /* Now we need to write a byte with the most significant bit set (0x80). */ 353 | ctx->cache[ctx->cacheLen] = 0x80; 354 | ctx->cacheLen += 1; 355 | 356 | /* If there isn't enough room for 8 bytes we need to padd with zeroes and get the block processed. */ 357 | cacheRemaining = sizeof(ctx->cache) - ctx->cacheLen; 358 | if (cacheRemaining < 8) { 359 | sha1_zero_memory(ctx->cache + ctx->cacheLen, cacheRemaining); 360 | sha1_update_block(ctx, ctx->cache); 361 | cacheRemaining = sizeof(ctx->cache); 362 | } 363 | 364 | /* Now we need to fill the buffer with zeros until we've filled 56 bytes (8 bytes left over for the length). */ 365 | sha1_zero_memory(ctx->cache + ctx->cacheLen, cacheRemaining - 8); 366 | 367 | szLo = (unsigned int)(((ctx->sz >> 0) & 0xFFFFFFFF) << 3); 368 | szHi = (unsigned int)(((ctx->sz >> 32) & 0xFFFFFFFF) << 3); 369 | ctx->cache[56] = (unsigned char)((szHi >> 24) & 0xFF); 370 | ctx->cache[57] = (unsigned char)((szHi >> 16) & 0xFF); 371 | ctx->cache[58] = (unsigned char)((szHi >> 8) & 0xFF); 372 | ctx->cache[59] = (unsigned char)((szHi >> 0) & 0xFF); 373 | ctx->cache[60] = (unsigned char)((szLo >> 24) & 0xFF); 374 | ctx->cache[61] = (unsigned char)((szLo >> 16) & 0xFF); 375 | ctx->cache[62] = (unsigned char)((szLo >> 8) & 0xFF); 376 | ctx->cache[63] = (unsigned char)((szLo >> 0) & 0xFF); 377 | sha1_update_block(ctx, ctx->cache); 378 | 379 | /* Now write out the digest. */ 380 | digest[ 0] = (unsigned char)(ctx->h[0] >> 24); digest[ 1] = (unsigned char)(ctx->h[0] >> 16); digest[ 2] = (unsigned char)(ctx->h[0] >> 8); digest[ 3] = (unsigned char)(ctx->h[0] >> 0); 381 | digest[ 4] = (unsigned char)(ctx->h[1] >> 24); digest[ 5] = (unsigned char)(ctx->h[1] >> 16); digest[ 6] = (unsigned char)(ctx->h[1] >> 8); digest[ 7] = (unsigned char)(ctx->h[1] >> 0); 382 | digest[ 8] = (unsigned char)(ctx->h[2] >> 24); digest[ 9] = (unsigned char)(ctx->h[2] >> 16); digest[10] = (unsigned char)(ctx->h[2] >> 8); digest[11] = (unsigned char)(ctx->h[2] >> 0); 383 | digest[12] = (unsigned char)(ctx->h[3] >> 24); digest[13] = (unsigned char)(ctx->h[3] >> 16); digest[14] = (unsigned char)(ctx->h[3] >> 8); digest[15] = (unsigned char)(ctx->h[3] >> 0); 384 | digest[16] = (unsigned char)(ctx->h[4] >> 24); digest[17] = (unsigned char)(ctx->h[4] >> 16); digest[18] = (unsigned char)(ctx->h[4] >> 8); digest[19] = (unsigned char)(ctx->h[4] >> 0); 385 | } 386 | 387 | SHA1_API void sha1(unsigned char* digest, const void* src, size_t sz) 388 | { 389 | sha1_context ctx; 390 | sha1_init(&ctx); 391 | { 392 | sha1_update(&ctx, src, sz); 393 | } 394 | sha1_finalize(&ctx, digest); 395 | } 396 | 397 | 398 | static void sha1_format_byte(char* dst, unsigned char byte) 399 | { 400 | const char* hex = "0123456789abcdef"; 401 | dst[0] = hex[(byte & 0xF0) >> 4]; 402 | dst[1] = hex[(byte & 0x0F) ]; 403 | } 404 | 405 | SHA1_API void sha1_format(char* dst, size_t dstCap, const unsigned char* hash) 406 | { 407 | size_t i; 408 | 409 | if (dst == NULL) { 410 | return; 411 | } 412 | 413 | if (dstCap < SHA1_SIZE_FORMATTED) { 414 | if (dstCap > 0) { 415 | dst[0] = '\0'; 416 | } 417 | 418 | return; 419 | } 420 | 421 | for (i = 0; i < SHA1_SIZE; i += 1) { 422 | sha1_format_byte(dst + (i*2), hash[i]); 423 | } 424 | 425 | /* Always null terminate. */ 426 | dst[SHA1_SIZE_FORMATTED-1] = '\0'; 427 | } 428 | #endif /* sha1_c */ 429 | #endif /* SHA1_IMPLEMENTATION */ 430 | 431 | /* 432 | This software is available as a choice of the following licenses. Choose 433 | whichever you prefer. 434 | 435 | =============================================================================== 436 | ALTERNATIVE 1 - Public Domain (www.unlicense.org) 437 | =============================================================================== 438 | This is free and unencumbered software released into the public domain. 439 | 440 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 441 | software, either in source code form or as a compiled binary, for any purpose, 442 | commercial or non-commercial, and by any means. 443 | 444 | In jurisdictions that recognize copyright laws, the author or authors of this 445 | software dedicate any and all copyright interest in the software to the public 446 | domain. We make this dedication for the benefit of the public at large and to 447 | the detriment of our heirs and successors. We intend this dedication to be an 448 | overt act of relinquishment in perpetuity of all present and future rights to 449 | this software under copyright law. 450 | 451 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 452 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 453 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 454 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 455 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 456 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 457 | 458 | For more information, please refer to 459 | 460 | =============================================================================== 461 | ALTERNATIVE 2 - MIT No Attribution 462 | =============================================================================== 463 | Copyright 2022 David Reid 464 | 465 | Permission is hereby granted, free of charge, to any person obtaining a copy of 466 | this software and associated documentation files (the "Software"), to deal in 467 | the Software without restriction, including without limitation the rights to 468 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 469 | of the Software, and to permit persons to whom the Software is furnished to do 470 | so. 471 | 472 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 473 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 474 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 475 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 476 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 477 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 478 | SOFTWARE. 479 | */ 480 | -------------------------------------------------------------------------------- /tests/sha1_test.c: -------------------------------------------------------------------------------- 1 | #define SHA1_IMPLEMENTATION 2 | #include "../sha1.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | int do_test(size_t iterationCount, const char* input, const char* expected) 9 | { 10 | unsigned char hash[SHA1_SIZE]; 11 | char hashStr[SHA1_SIZE_FORMATTED]; 12 | sha1_context ctx; 13 | 14 | sha1_init(&ctx); 15 | { 16 | size_t i; 17 | size_t inputSize = strlen(input); 18 | for (i = 0; i < iterationCount; i += 1) { 19 | sha1_update(&ctx, input, inputSize); 20 | } 21 | } 22 | sha1_finalize(&ctx, hash); 23 | 24 | /* Check and compare results. */ 25 | sha1_format(hashStr, sizeof(hashStr), hash); 26 | 27 | printf("%s = %s : ", input, hashStr); 28 | if (strcmp(hashStr, expected) == 0) { 29 | printf("success\n"); 30 | return 0; 31 | } else { 32 | printf("failed\n"); 33 | return -1; 34 | } 35 | } 36 | 37 | int main(int argc, char** argv) 38 | { 39 | (void)argc; 40 | (void)argv; 41 | 42 | do_test(1, "", "da39a3ee5e6b4b0d3255bfef95601890afd80709"); 43 | do_test(1, "a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"); 44 | do_test(1, "abc", "a9993e364706816aba3e25717850c26c9cd0d89d"); 45 | do_test(1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1"); 46 | do_test(1000000, "a", "34aa973cd4c4daa4f61eeb2bdbad27316534016f"); 47 | do_test(1, "0123456701234567012345670123456701234567012345670123456701234567", "e0c094e867ef46c350ef54a7f59dd60bed92ae83"); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/sha1_test.cpp: -------------------------------------------------------------------------------- 1 | #include "sha1_test.c" 2 | --------------------------------------------------------------------------------