⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha.cpp

📁 agsm a gsm sim manager for browsing, managing, and manipulating the phonebook,SMS on the SIM card. I
💻 CPP
字号:
/* "sha.c" */
#include "stdafx.h"
#include "sha.h"

static unsigned long A, B, C, D, E;

#define K1	0x5a827999
#define K2	0x6ed9eba1
#define K3	0x8f1bbcdc
#define K4	0xca62c1d6

#define S(a,n) ((a << n) | (a >> (32-n)))

static
unsigned char SHA_IV[20] = { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89,
							 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76,
							 0xc3, 0xd2, 0xe1, 0xf0 };

/* SHA ft(B,C,D) + Kt */

static unsigned long ftk(int t)
{
	if (t < 20)
		return( ((B & C) | (~B & D)) + K1 );
	else if (t < 40)
		return( (B ^ C ^ D) + K2 );
	else if (t < 60)
		return( ((B & C) | (B & D) | (C & D)) + K3 );
	else
		return( (B ^ C ^ D) + K4 );
}

/* the 80 rounds of SHA */

static
void shaHash(SHA_INFO *sha_info)
{
	unsigned long t, A0, B0, C0, D0, E0, W[16];
	int i, s;

	/* set the temporary digest values from the current digest,
	   using shifts to ensure machine-independence */

	A  = (unsigned long)sha_info->digest[0] << 24;
	A += (unsigned long)sha_info->digest[1] << 16;
	A += (unsigned long)sha_info->digest[2] << 8;
	A += (unsigned long)sha_info->digest[3];
	B  = (unsigned long)sha_info->digest[4] << 24;
	B += (unsigned long)sha_info->digest[5] << 16;
	B += (unsigned long)sha_info->digest[6] << 8;
	B += (unsigned long)sha_info->digest[7];
	C  = (unsigned long)sha_info->digest[8] << 24;
	C += (unsigned long)sha_info->digest[9] << 16;
	C += (unsigned long)sha_info->digest[10] << 8;
	C += (unsigned long)sha_info->digest[11];
	D  = (unsigned long)sha_info->digest[12] << 24;
	D += (unsigned long)sha_info->digest[13] << 16;
	D += (unsigned long)sha_info->digest[14] << 8;
	D += (unsigned long)sha_info->digest[15];
	E  = (unsigned long)sha_info->digest[16] << 24;
	E += (unsigned long)sha_info->digest[17] << 16;
	E += (unsigned long)sha_info->digest[18] << 8;
	E += (unsigned long)sha_info->digest[19];

	/* save A-E */

	A0 = A;
	B0 = B;
	C0 = C;
	D0 = D;
	E0 = E;

	/* move the data into the first 16 words of W */

	for (i = 0; i < 16; i++)
		W[i] = sha_info->data[i];

	/* perform the 80 rounds, using the "alternate method" in which
	   the later values of W are computed in place */

	for (i = 0; i < 80; i++)
	{
		s = i & 0x0f;

		if (i >= 16)
		{
			t = W[(i-3) & 0x0f] ^ W[(i-8) & 0x0f] ^
				W[(i-14)&0x0f] ^ W[s];
			W[s] = S(t,1);
		}

		t = S(A,5) + ftk(i) + E + W[s];
		E = D;
		D = C;
		C = S(B,30);
		B = A;
		A = t;
	}

	/* add in the original values of A-E */

	A += A0;
	B += B0;
	C += C0;
	D += D0;
	E += E0;

	/* save resulting digest, again using shifts to ensure
	   machine independence */

	sha_info->digest[0] = (unsigned char)(A >> 24);
	sha_info->digest[1] = (unsigned char)((A >> 16) & 0xff);
	sha_info->digest[2] = (unsigned char)((A >> 8) & 0xff);
	sha_info->digest[3] = (unsigned char)(A & 0xff);
	sha_info->digest[4] = (unsigned char)(B >> 24);
	sha_info->digest[5] = (unsigned char)((B >> 16) & 0xff);
	sha_info->digest[6] = (unsigned char)((B >> 8) & 0xff);
	sha_info->digest[7] = (unsigned char)(B & 0xff);
	sha_info->digest[8] = (unsigned char)(C >> 24);
	sha_info->digest[9] = (unsigned char)((C >> 16) & 0xff);
	sha_info->digest[10] = (unsigned char)((C >> 8) & 0xff);
	sha_info->digest[11] = (unsigned char)(C & 0xff);
	sha_info->digest[12] = (unsigned char)(D >> 24);
	sha_info->digest[13] = (unsigned char)((D >> 16) & 0xff);
	sha_info->digest[14] = (unsigned char)((D >> 8) & 0xff);
	sha_info->digest[15] = (unsigned char)(D & 0xff);
	sha_info->digest[16] = (unsigned char)(E >> 24);
	sha_info->digest[17] = (unsigned char)((E >> 16) & 0xff);
	sha_info->digest[18] = (unsigned char)((E >> 8) & 0xff);
	sha_info->digest[19] = (unsigned char)(E & 0xff);

	/* clear the data so that further updates can be added in */

	for (i = 0; i < 16; i++)
		sha_info->data[i] = 0;
}

/* initialize sha_info */

void shaInitial(SHA_INFO *sha_info)
{
	int i;

	/* set digest to its initial value.  Done one char at a time
	   to ensure machine independence. */

	for (i = 0; i < 20; i++)
		sha_info->digest[i] = SHA_IV[i];

	/* clear data so that updates can be added in */

	for (i = 0; i < 16; i++)
		sha_info->data[i] = 0;

	/* set bit count to zero */

	sha_info->count[0] = sha_info->count[1] = 0;
}

/* update the digest using additional message data */

void shaUpdate(SHA_INFO *sha_info,
			   unsigned char *buffer,
			   unsigned long offset,
			   unsigned long count)
{
	unsigned long data_count, t, mask_size;
	unsigned char *bptr, c, last, mask;

	/* enter the message data into the data buffer.  When the buffer
	   is full (512 bits entered, update the digest and clear the
	   data buffer for the next update.  */

	data_count = sha_info->count[1]%512;
	bptr = buffer + (offset/8);


	/* first fill the current octet of the buffer, so that
	   the bit offset into the buffer is a multiple of 8 */
	last = *bptr++;
	if (data_count%8)
	{
		/* get a full byte from the buffer */
		c = last;
		last = *bptr++;
		if (offset%8)
		{
			c <<= (offset%8);
			c += last >> (8 - (offset%8));
		}

		/* set mask to fill the remaining bits of the octet */
		mask_size = 8 - (data_count%8);
		mask = 0xff << (data_count%8);

		/* adjust for short count */
		if (count < mask_size)
		{
			mask <<= (mask_size-count);
			mask_size = count;
		}

		/* store the bits */
		c = (c & mask) >> (data_count%8);
		sha_info->data[data_count/32] += (unsigned long)c << 8*(3 - ((data_count%32)/8));

		/* update count */
		t = sha_info->count[1];
		sha_info->count[1] += mask_size;
		if (sha_info->count[1] < t)
			sha_info->count[0]++;

		/* if the data buffer is full, update the digest */
		data_count += mask_size;
		if (data_count == 512)
		{
			shaHash(sha_info);
			data_count = 0;
		}

		/* start over with updated offset and count */
		offset += mask_size;
		count -= mask_size;
		bptr = buffer + (offset/8);
		last = *bptr++;
	}
	while (count != 0)
	{
		/* get the next full octet from the buffer */
		c = last;
		last = *bptr++;
		if (offset%8)
		{
			c <<= (offset%8);
			c += last >> (8 - (offset%8));
		}

		/* set mask to a full octet */
		mask_size = 8;
		mask = 0xff;

		/* adjust for short count */
		if (count < mask_size)
		{
			mask <<= (mask_size-count);
			mask_size = count;
		}

		/* store the bits */
		c &= mask;
		sha_info->data[data_count/32] += (unsigned long)c << 8*(3 - ((data_count%32)/8));

		/* update count */
		t = sha_info->count[1];
		sha_info->count[1] += mask_size;
		if (sha_info->count[1] < t)
			sha_info->count[0]++;

		/* if the data buffer is full, update the digest */
		data_count += mask_size;
		if (data_count == 512)
		{
                        shaHash(sha_info);
			data_count = 0;
		}

		count -= mask_size;
	}
}

/* add pad bit of '1', zero fill and bit length, then update the digest */

void shaFinal(SHA_INFO *sha_info)
{
	/* add the pad bit of '1' */

	sha_info->data[(sha_info->count[1]%512)/32] +=
		1L << (31 - (sha_info->count[1]%32));

	/* if the data buffer is full, update the digest */

	if ((sha_info->count[1]%512) == 511)
		shaHash(sha_info);

	/* if there isn't room for 64 bits of bit length, leave the
	   buffer zero filled to the end, update the digest and clear
	   the buffer.  */

	if ((sha_info->count[1]%512) > (512-65))
		shaHash(sha_info);

	/* put in the bit length */

	sha_info->data[14] = sha_info->count[0];
	sha_info->data[15] = sha_info->count[1];

	/* update the digest */

	shaHash(sha_info);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -