/******************************************************************************* * Teeny SHA-1 * * The below sha1digest() calculates a SHA-1 hash value for a * specified data buffer and generates a hex representation of the * result. This implementation is a re-forming of the SHA-1 code at * https://github.com/jinqiangshou/EncryptionLibrary. * * Copyright (c) 2017 CTrabant * * License: MIT, see included LICENSE file for details. * * To use the sha1digest() function either copy it into an existing * project source code file or include this file in a project and put * the declaration (example below) in the sources files where needed. ******************************************************************************/ #include #include #include #include #define SWAB(a) ((a>>24) | ((a & 0x00ff0000>>8)) | ((a &0x0000ff00) <<8) | (a<<24)) uint32_t key[] = { 0x6e380e89, 0xe9cf3cbb, 0xe44f0000 }; uint32_t k1 = 0x5A827999; uint32_t k2 = 0x6ED9EBA1; uint32_t k3 = 0x8F1BBCDC; uint32_t k4 = 0xCA62C1D6; uint32_t ffffffff = 0xffffffff; uint32_t va, vb, vc, vd, ve, t1, t2, zero; uint32_t data[6]; uint32_t data2; uint32_t key_or; uint8_t lidx; uint8_t idx; uint32_t H[5]; uint32_t Wbuf[16]; uint32_t HI[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; #define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) void set_key_or (uint8_t v) { key_or = v; key_or <<= 8; key_or |= v; key_or <<= 8; key_or |= v; key_or <<= 8; key_or |= v; } void get_w32_015_to_t2 (int idx) { uint32_t t1; if (!lidx) { if (idx < 3) { t2 = key[idx] + zero; } else { t2 = zero + zero; } t2 = t2 ^ key_or; return; } if (idx < 6) { t2 = data[idx]; return; } if (idx < 15) { t2 = 0; return; } t2 = data2; } uint32_t get_w32_to_t2 (void) { int i; for (i = 0; i < 16; ++i) { get_w32_015_to_t2 (i); Wbuf[i] = zero + t2; } if (idx < 16) { t2 = zero + Wbuf[idx]; return; } i = idx - 16; while (1) { t2 = Wbuf[13] ^ Wbuf[8]; t2 = t2 ^ Wbuf[2]; t2 = t2 ^ Wbuf[0]; t2 = SHA1ROTATELEFT (t2, 1); if (!i) return; memmove (Wbuf, Wbuf + 1, 60); Wbuf[15] = t2; i--; } } void do_sha1digest (void) { uint32_t k; va = H[0]; vb = H[1]; vc = H[2]; vd = H[3]; ve = H[4]; for (idx = 0; idx <= 79; idx++) { if (idx <= 19) { k = k1; t2 = vb ^ ffffffff; t2 = t2 & vd; t1 = vb & vc; t1 = t2 | t1; } else if (idx >= 20 && idx <= 39) { k = k2; t1 = vb ^ vc; t1 = t1 ^ vd; } else if (idx >= 40 && idx <= 59) { k = k3; t1 = vd & vb; t2 = vc & vd; t2 = t1 | t2; t1 = vb & vc; t1 = t2 | t1; } else if (idx >= 60 && idx <= 79) { k = k4; t1 = vb ^ vc; t1 = t1 ^ vd; } t1 = t1 + ve; t1 = t1 + k; get_w32_to_t2 (); t1 = t1 + t2; ve = vd; vd = vc; vc = vb; vc = SHA1ROTATELEFT (vc, 30); vb = va; va = SHA1ROTATELEFT (va, 5); va = va + t1; } H[0] += va; H[1] += vb; H[2] += vc; H[3] += vd; H[4] += ve; } void show_w2 (void) { printf ("w2="); for (idx = 0; idx < 80; ++idx) { get_w32_to_t2 (); printf ("%08x", SWAB (t2)); } printf ("\n"); } void show_data(void) { printf ("out="); for (idx = 0; idx < 5; ++idx) { printf ("%08x", data[idx]); } printf ("\n"); } void sha1digest (void) { memcpy (H, HI, 20); lidx = 0; show_w2 (); do_sha1digest (); lidx = 1; show_w2 (); do_sha1digest (); memcpy(data,H,20); show_data(); } /* End of sha1digest() */ int main (int argc, char *argv[]) { uint32_t t = 0xa7a6; int a; data[0] = 0; data[1] = t; data[2] = zero; data[2] ^= 0x80000000; data2 = 0x00000240; data[3] = zero; data[4] = zero; data[5] = zero; set_key_or (0x36); sha1digest (); data[5] ^= 0x80000000; data2 = 0x000002a0; set_key_or (0x5c); sha1digest (); a=data[4] &0x0f; t1=*(uint32_t*)( a+ (uint8_t *) data); t1&=0x7fffffff; printf("%d\n",t1); return 0; }