📄 sha1.c
字号:
return;}static voidsha1_swallow (ULONG *stomach, ULONG *ULBlock){ int round; ULONG x; ULONG a = stomach[0]; ULONG b = stomach[1]; ULONG c = stomach[2]; ULONG d = stomach[3]; ULONG e = stomach[4]; /*lint -e123 Don't complain about "Macros ... defined with arguments" */ for (round = 0; round < 16; round++) { x = ROL((a), 5) + (d^(b&(c^d))) + e + ULBlock[round] + 0x5A827999L; CHAIN (a, b, c, d, e, x); } for (round = 16; round < 20; round++) { x = ROL((a), 5) + (d^(b&(c^d))) + e + XPND(ULBlock, round) + 0x5A827999L; CHAIN (a, b, c, d, e, x); } for (round = 20; round < 40; round++) { x = ROL((a), 5) + (b^c^d) + e + XPND(ULBlock, round) + 0x6ED9EBA1L; CHAIN (a, b, c, d, e, x); } for (round = 40; round < 60; round++) { x = ROL((a), 5) + ((b&c)|(d&(b|c))) + e + XPND(ULBlock, round) + 0x8F1BBCDCL; CHAIN (a, b, c, d, e, x); } for (round = 60; round < 80; round++) { x = ROL((a), 5) + (b^c^d) + e + XPND(ULBlock, round) + 0xCA62C1D6L; CHAIN (a, b, c, d, e, x); } /* Result in stomach */ stomach[0] += a; stomach[1] += b; stomach[2] += c; stomach[3] += d; stomach[4] += e;#ifdef FLINT_SECURE /* Overwrite temporary variables */ Zero4Ulong (&a, &b, &c, &d); ZeroUlong (&e);#endif return;}static voidsha1_digest (ULONG *stomach, UCHAR *clear, ULONG total[]){ ULONG i,j, k, rest; ULONG ULBlock[16]; memset (ULBlock, 0, sizeof (ULONG) << 4); /* Padding to achieve block lengthe of 512 Bit */ /* by example of the message "abc" of length l = 24 bit: */ /* 1. One bit "1" is appended to the end of the masseage. */ /* 2. k "0"-bits are appended, with k the smallest non-negative */ /* solution of l+1+k = 448 mod 512, in this example k = 448-1-24 */ /* = 423, 7 bit following the single "1" plus additional */ /* 13 ULONGs (i.e. 416 bit) in the positions ULBlock[1]...[13]. */ /* 3. The length of the message is appended in 64 bit (2 ULONGs). */ /* Note: Opposite to MD4, MD5 and RIPEMD MSW is stored first and */ /* LSW is preceding MSW. */ /* */ /* 01100001 01100010 01100011 1 000...00 00...011000 */ /* "a" "b" "c" 1+ 423Bit 64 bit (length) */ /* Message length modulo 64 ULONG-blocks (512 bit) */ rest = total[0] & 0x3f; /* Insert ULONGs into ULBlock */ for (i = 0; i < (rest >> 2); i++) { ULBlock[i] = UC2ULBE (clear); clear += 4; } /* Remaining UCHARs go into ULBLock. Invariant: 0 <= i <= 15 */ for (j = i << 2, k = 3; j < rest; j++, k--) { ULBlock[i] |= (ULONG)*clear++ << (k << 3); } /* Append 0x80 to ULBlock: At least one byte is still free */ ULBlock[i] |= (ULONG)0x80 << (k << 3); if (rest > 55) /* No space left for appending the message length (8 Byte), */ { /* therefore store length into the following block */ sha1_swallow (stomach, ULBlock); memset (ULBlock, 0, sizeof (ULONG) << 4); } /* Append message length in bit, MSW first, LSW preceding MSW */ ULBlock[14] = (total[0] >> 29) | (total[1] << 3); ULBlock[15] = total[0] << 3; sha1_swallow (stomach, ULBlock);#ifdef FLINT_SECURE /* Overwrite temporary variables */ Zero4Ulong (&ULBlock[0], &ULBlock[1], &ULBlock[2], &ULBlock[3]); Zero4Ulong (&ULBlock[4], &ULBlock[5], &ULBlock[6], &ULBlock[7]); Zero4Ulong (&ULBlock[8], &ULBlock[9], &ULBlock[10], &ULBlock[11]); Zero4Ulong (&ULBlock[12], &ULBlock[13], &ULBlock[14], &ULBlock[15]);#endif return;}#ifdef FLINT_SECURE/******************************************************************************//* *//* Function: Purging of variables *//* Syntax: ZeroUlong (ULONG *a); *//* Input: ULONG *a (Pointer to ULONG variable to be purged) *//* Output: *a overwritten by 0 *//* Returns: - *//* *//******************************************************************************/static inline void ZeroUlong (ULONG *a){ *a = 0;}/******************************************************************************//* *//* Function: Purging of variables *//* Syntax: Zero2Ulong (ULONG *a, ULONG *b); *//* Input: ULONG *a (Pointer to ULONG variable to be purged) *//* ULONG *b (Pointer to ULONG variable to be purged) *//* Output: *a, *b overwritten by 0 *//* Returns: - *//* *//******************************************************************************/static inline void Zero2Ulong (ULONG *a, ULONG *b){ *a = *b = 0;}/******************************************************************************//* *//* Function: Purging of variables *//* Syntax: Zero4Ulong (ULONG *a, ULONG *b, ULONG *c, ULONG *d); *//* Input: ULONG *a (Pointer to ULONG variable to be purged) *//* ULONG *b (Pointer to ULONG variable to be purged) *//* ULONG *c (Pointer to ULONG variable to be purged) *//* ULONG *d (Pointer to ULONG variable to be purged) *//* Output: *a, *b, *c and *d overwritten by 0 *//* Returns: - *//* *//******************************************************************************/static inline void Zero4Ulong (ULONG *a, ULONG *b, ULONG *c, ULONG *d){ *a = *b = *c = *d = 0;}/******************************************************************************//* *//* Function: Purging of Array *//* Syntax: ZeroUcharArray (UCHAR *a, int Len); *//* Input: UCHAR *a (Pointer to array of UCHARs) *//* int Len (Length of array in byte) *//* Output: Array overwritten by 0 *//* Returns: - *//* *//******************************************************************************/static inline void ZeroUcharArray (void *a, size_t Len){ memset ((UCHAR*)a, 0, Len);}#endif#ifdef SHA1_TESTunsigned char digest[20];unsigned char message[3] = {'a', 'b', 'c' };unsigned char *mess56 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";/* Correct solutions from FIPS PUB 180-1 */char *dig1 = "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D";char *dig2 = "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1";char *dig3 = "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F";/* Output should look like:- a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D <= correct 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 <= correct 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F <= correct*/main(){ SHASTAT sha; int i; UCHAR big[1000]; sha1init (&sha); sha1finish (digest, &sha, message, 3); for (i = 0; i < 20; i++) { if ((i % 4) == 0) printf(" "); printf("%02x", digest[i]); } printf ("\n"); printf (" %s <= correct\n", dig1); sha1init (&sha); sha1finish (digest, &sha, mess56, 56); for (i = 0; i < 20; i++) { if ((i % 4) == 0) printf(" "); printf ("%02x", digest[i]); } printf ("\n"); printf (" %s <= correct\n", dig2); /* Fill up big array */ for (i = 0; i < 1000; i++) big[i] = 'a'; sha1init (&sha); /* Digest 1 million x 'a' */ for (i = 0; i < 1041; i++) sha1hash (&sha, big, 960); sha1finish (digest, &sha, big, 640); for (i = 0; i < 20; i++) { if ((i % 4) == 0) printf(" "); printf("%02x", digest[i]); } printf("\n"); printf(" %s <= correct\n", dig3); return 0;}#endif /* SHA1_TEST? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -