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

📄 pgpsha384_512.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

  Generic implementation of SHA 384 and SHA 512. Works on any 32 bit platform.
  File sha384_512_64.c should be used instead of this file for efficiency reason, if possible.

	$Id: pgpSHA384_512.c,v 1.3 2002/08/06 20:10:59 dallen Exp $
____________________________________________________________________________*/

#include "pgpConfig.h"
#include <string.h>

#include "pgpHash.h"
#include "pgpSHA2.h"
#include "pgpDebug.h"

#if !defined(PGP_HAVE64) || !PGP_HAVE64 /* [ */

typedef struct word64_  {
#ifdef SHA512_BIG_ENDIAN
	PGPUInt32 high;
	PGPUInt32 low;
#else
	PGPUInt32 low;		/* little endian */
	PGPUInt32 high;
#endif
} word64;
typedef word64 sha512_word;
#define SHA512_BITS_IN_WORD 64


#ifdef SHA512_BIG_ENDIAN
#define swap_sha512_word(d,s) *(d)=*(s)
#else
static void swap_sha512_word(const sha512_word *d, sha512_word *s) {
	((PGPByte*)d)[0] = ((PGPByte*)s)[7];
	((PGPByte*)d)[1] = ((PGPByte*)s)[6];
	((PGPByte*)d)[2] = ((PGPByte*)s)[5];
	((PGPByte*)d)[3] = ((PGPByte*)s)[4];
	((PGPByte*)d)[4] = ((PGPByte*)s)[3];
	((PGPByte*)d)[5] = ((PGPByte*)s)[2];
	((PGPByte*)d)[6] = ((PGPByte*)s)[1];
	((PGPByte*)d)[7] = ((PGPByte*)s)[0];
}
#endif

/* right rotation of x by n bits, n < 32 */
static void S_l(sha512_word * const d, const sha512_word * const s, unsigned n)  {
	pgpAssert( n<32 );

	d->low = (s->low >> n) | (s->high << (sizeof(s->high)*8 - n));
	d->high = (s->high >> n) | (s->low << (sizeof(s->low)*8 - n));
}

/* right rotation for more then 32 bits; n is original_n-32 */
static void S_h(sha512_word * const d, const sha512_word * const s, unsigned n)  {
	pgpAssert( n<32 );

	d->low = (s->high >> n) | (s->low << (sizeof(s->low)*8 - n));
	d->high = (s->low >> n) | (s->high << (sizeof(s->high)*8 - n));
}

/* shift right for less then 32 bits (operator>>) */
static void shl(sha512_word * const d, const sha512_word * const s, unsigned n)  {
	d->low = (s->low >> n) | (s->high << (sizeof(s->low)*8-n));
	d->high = s->high >> n;
}

/* operator ^= */
static void xor(sha512_word * const d, const sha512_word * const s)  {
	d->low ^= s->low;
	d->high ^= s->high;
}

/* operator &= */
static void and(sha512_word * const d, const sha512_word * const s)  {
	d->low &= s->low;
	d->high &= s->high;
}

/* operator ~ */
static void neg(sha512_word * const d)  {
	d->low  = ~d->low;
	d->high = ~d->high;
}

/* operator += */
static void add(sha512_word * const d, const sha512_word * const s)  {
	PGPUInt32 t = d->low;
	d->high += (( d->low += s->low ) < t) + s->high;
}


typedef sha512_word sha512_message[16];	/* 1024 bit message */

/* constant words for SHA 384 and SHA 512 */
#ifdef SHA512_BIG_ENDIAN
#define W(a,b) a,b
#else
#define W(a,b) b,a
#endif
static const sha512_word K[80] = {
W(0x428a2f98,0xd728ae22),W(0x71374491,0x23ef65cd),W(0xb5c0fbcf,0xec4d3b2f),W(0xe9b5dba5,0x8189dbbc),
W(0x3956c25b,0xf348b538),W(0x59f111f1,0xb605d019),W(0x923f82a4,0xaf194f9b),W(0xab1c5ed5,0xda6d8118),
W(0xd807aa98,0xa3030242),W(0x12835b01,0x45706fbe),W(0x243185be,0x4ee4b28c),W(0x550c7dc3,0xd5ffb4e2),
W(0x72be5d74,0xf27b896f),W(0x80deb1fe,0x3b1696b1),W(0x9bdc06a7,0x25c71235),W(0xc19bf174,0xcf692694),
W(0xe49b69c1,0x9ef14ad2),W(0xefbe4786,0x384f25e3),W(0x0fc19dc6,0x8b8cd5b5),W(0x240ca1cc,0x77ac9c65),
W(0x2de92c6f,0x592b0275),W(0x4a7484aa,0x6ea6e483),W(0x5cb0a9dc,0xbd41fbd4),W(0x76f988da,0x831153b5),
W(0x983e5152,0xee66dfab),W(0xa831c66d,0x2db43210),W(0xb00327c8,0x98fb213f),W(0xbf597fc7,0xbeef0ee4),
W(0xc6e00bf3,0x3da88fc2),W(0xd5a79147,0x930aa725),W(0x06ca6351,0xe003826f),W(0x14292967,0x0a0e6e70),
W(0x27b70a85,0x46d22ffc),W(0x2e1b2138,0x5c26c926),W(0x4d2c6dfc,0x5ac42aed),W(0x53380d13,0x9d95b3df),
W(0x650a7354,0x8baf63de),W(0x766a0abb,0x3c77b2a8),W(0x81c2c92e,0x47edaee6),W(0x92722c85,0x1482353b),
W(0xa2bfe8a1,0x4cf10364),W(0xa81a664b,0xbc423001),W(0xc24b8b70,0xd0f89791),W(0xc76c51a3,0x0654be30),
W(0xd192e819,0xd6ef5218),W(0xd6990624,0x5565a910),W(0xf40e3585,0x5771202a),W(0x106aa070,0x32bbd1b8),
W(0x19a4c116,0xb8d2d0c8),W(0x1e376c08,0x5141ab53),W(0x2748774c,0xdf8eeb99),W(0x34b0bcb5,0xe19b48a8),
W(0x391c0cb3,0xc5c95a63),W(0x4ed8aa4a,0xe3418acb),W(0x5b9cca4f,0x7763e373),W(0x682e6ff3,0xd6b2b8a3),
W(0x748f82ee,0x5defb2fc),W(0x78a5636f,0x43172f60),W(0x84c87814,0xa1f0ab72),W(0x8cc70208,0x1a6439ec),
W(0x90befffa,0x23631e28),W(0xa4506ceb,0xde82bde9),W(0xbef9a3f7,0xb2c67915),W(0xc67178f2,0xe372532b),
W(0xca273ece,0xea26619c),W(0xd186b8c7,0x21c0c207),W(0xeada7dd6,0xcde0eb1e),W(0xf57d4f7f,0xee6ed178),
W(0x06f067aa,0x72176fba),W(0x0a637dc5,0xa2c898a6),W(0x113f9804,0xbef90dae),W(0x1b710b35,0x131c471b),
W(0x28db77f5,0x23047d84),W(0x32caab7b,0x40c72493),W(0x3c9ebe0a,0x15c9bebc),W(0x431d67c4,0x9c100d4c),
W(0x4cc5d4be,0xcb3e42b6),W(0x597f299c,0xfc657e2a),W(0x5fcb6fab,0x3ad6faec),W(0x6c44198c,0x4a475817)
};

/* 256 bit SHA register set */
typedef struct SHA512_REGS_  {
	sha512_word a;
	sha512_word b;
	sha512_word c;
	sha512_word d;
	sha512_word e;
	sha512_word f;
	sha512_word g;
	sha512_word h;
} SHA512_REGS;

/* 128 bit length */
typedef struct SHA512_LENGTH_  {
	word64 low;
	word64 high;
} SHA512_LENGTH;
typedef SHA512_LENGTH sha512_length;	

#ifdef SHA512_TEST
static void
sha512_print(SHA512_REGS *H)  {
	printf( "%08x%08x %08x%08x %08x%08x %08x%08x\n%08x%08x %08x%08x %08x%08x %08x%08x\n",  
		H->a.high,H->a.low, H->b.high,H->b.low,	H->c.high,H->c.low, H->d.high,H->d.low,
		H->e.high,H->e.low, H->f.high,H->f.low,	H->g.high,H->g.low, H->h.high,H->h.low
	);
}
#define SHA512_PRINT(H) sha512_print(H)
#else
#define SHA512_PRINT(H) 
#endif


/* Shuffle the bytes into big-endian order within words, as per the
   SHA spec. 
 */
#ifndef SHA512_BIG_ENDIAN
static void sha256WordSwapInPlace(sha512_word * s, unsigned words)
{
	unsigned t;

	while(words--)  {
		t = ((PGPByte*)s)[0]; ((PGPByte*)s)[0] = ((PGPByte*)s)[7]; ((PGPByte*)s)[7] = t;
		t = ((PGPByte*)s)[1]; ((PGPByte*)s)[1] = ((PGPByte*)s)[6]; ((PGPByte*)s)[6] = t;
		t = ((PGPByte*)s)[2]; ((PGPByte*)s)[2] = ((PGPByte*)s)[5]; ((PGPByte*)s)[5] = t;
		t = ((PGPByte*)s)[3]; ((PGPByte*)s)[3] = ((PGPByte*)s)[4]; ((PGPByte*)s)[4] = t;
		s++;
	}
}
#else
#define sha256WordSwapInPlace(s,words)
#endif



static void sha512Add( sha512_length *l, unsigned u )  {
	PGPUInt32 t;

	t = l->low.low;
	if ( ( l->low.low = t + u ) < t )  {
		if( !(++l->low.high) ||	!(++l->high.low) )
			l->high.high++;
	}
}

static void sha512Mul8( sha512_length *l )  {
	l->high.high = (l->high.high << 3) | (l->high.low >> (sizeof(l->high.high)*8-3));
	l->high.low = (l->high.low << 3) | (l->low.high >> (sizeof(l->high.low)*8-3));
	l->low.high = (l->low.high << 3) | (l->low.low >> (sizeof(l->low.high)*8-3));
	l->low.low <<= 3;
}


/* initialise SHA registers */
static void sha384_init( SHA512_REGS * const H )  
{
	H->a.high = 0xcbbb9d5d;	H->a.low = 0xc1059ed8;
	H->b.high = 0x629a292a;	H->b.low = 0x367cd507;
	H->c.high = 0x9159015a;	H->c.low = 0x3070dd17;
	H->d.high = 0x152fecd8;	H->d.low = 0xf70e5939;
	H->e.high = 0x67332667;	H->e.low = 0xffc00b31;
	H->f.high = 0x8eb44a87;	H->f.low = 0x68581511;
	H->g.high = 0xdb0c2e0d;	H->g.low = 0x64f98fa7;
	H->h.high = 0x47b5481d;	H->h.low = 0xbefa4fa4;
}
static void sha512_init( SHA512_REGS * const H )  
{
	H->a.high = 0x6a09e667;	H->a.low = 0xf3bcc908;
	H->b.high = 0xbb67ae85;	H->b.low = 0x84caa73b;
	H->c.high = 0x3c6ef372;	H->c.low = 0xfe94f82b;
	H->d.high = 0xa54ff53a;	H->d.low = 0x5f1d36f1;
	H->e.high = 0x510e527f;	H->e.low = 0xade682d1;
	H->f.high = 0x9b05688c;	H->f.low = 0x2b3e6c1f;
	H->g.high = 0x1f83d9ab;	H->g.low = 0xfb41bd6b;
	H->h.high = 0x5be0cd19;	H->h.low = 0x137e2179;
}

/* Processes 512 bit message block M. 
  
	Words in M are big endian, so this function performs word swap. Placing 
	swap here saves one memcpy.

   No partial blocks here (padding is not performed in this function) */
static void sha512_process( SHA512_REGS * const H, const sha512_message M[] )  {
	int t;				/* counter */

	sha512_word T1, T2, T3, T4;	/* temporary variables */
	sha512_word W[80];	/* 80*64=5120 bit message schedule */

	SHA512_REGS r = *H;			

	/* fill message schedule W[i], i=[0..15], swapping words */
	swap_sha512_word( W+0,  ((sha512_word*)M)+0 );
	swap_sha512_word( W+1,  ((sha512_word*)M)+1 );
	swap_sha512_word( W+2,  ((sha512_word*)M)+2 );
	swap_sha512_word( W+3,  ((sha512_word*)M)+3 );
	swap_sha512_word( W+4,  ((sha512_word*)M)+4 );
	swap_sha512_word( W+5,  ((sha512_word*)M)+5 );
	swap_sha512_word( W+6,  ((sha512_word*)M)+6 );
	swap_sha512_word( W+7,  ((sha512_word*)M)+7 );
	swap_sha512_word( W+8,  ((sha512_word*)M)+8 );
	swap_sha512_word( W+9,  ((sha512_word*)M)+9 );
	swap_sha512_word( W+10, ((sha512_word*)M)+10 );
	swap_sha512_word( W+11, ((sha512_word*)M)+11 );
	swap_sha512_word( W+12, ((sha512_word*)M)+12 );
	swap_sha512_word( W+13, ((sha512_word*)M)+13 );
	swap_sha512_word( W+14, ((sha512_word*)M)+14 );
	swap_sha512_word( W+15, ((sha512_word*)M)+15 );

	/* fill message schedule W[i], i=[16..80] */
	for( t=16; t<80; t++ )  {
		/* calculate W[t] = ( S(W[t-2],19) ^ S(W[t-2],61) ^ (W[t-2]>>6) ) + W[t-7] + W[t-16]; */
		S_l( &T2, W+t-2, 19 );
		S_h( &T1, W+t-2, 61 & (32-1));
		xor( &T1, &T2 );

		shl( &T2, W+t-2, 6 );
		xor( &T1, &T2 );		/* T1 = sigma1( W[t-2] ) */

		add( &T1, W+t-7 );
		add( &T1, W+t-16 );

		W[t] = T1;

		/* calculate W[t] += S(W[t-15],1) ^ S(W[t-15],8) ^ (W[t-15] >> 7); */
		S_l(&T1,W+t-15,1);
		S_l(&T2,W+t-15,8);
		xor( &T1, &T2 );

		shl( &T2, W+t-15, 7 );
		xor( &T1, &T2 );		/* T1 = sigma0( W[t-16] ) */

		add( W+t, &T1 );
/*#ifdef SHA512_TEST
		printf( "%08x%08x\n", W[t].high, W[t].low  );
#endif*/
	}

	/* hash */
	for( t=0; t<80; t++ )  {

		/* calculate T1 = r.h +
			( S(r.e,14) ^ S(r.e,18) ^ S(r.e,41) ) +		(= Sum1(e) ) 
			( (r.e & r.f) ^ ((~r.e) & r.g)) +			(= Ch(e,f,g) )
			K[t] + W[t]; */

		S_l( &T3, &r.e, 14 );
		S_l( &T4, &r.e, 18 );
		xor( &T3, &T4 );
		S_h( &T4, &r.e, 41 & (32-1) );
		xor( &T3, &T4 );				/* T3 = Sum1(e) */

		T1 = r.f;
		T2 = r.e;
		and( &T1, &T2 );
		neg( &T2 );

⌨️ 快捷键说明

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