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

📄 pgpsha384_512.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
		and( &T2, &r.g );
		xor( &T1, &T2 );				/* T1 = Ch(e,f,g) */

		add( &T1, &r.h );
		add( &T1, &T3 );
		add( &T1, K+t );
		add( &T1, W+t );


		/* calculate T2 = ( S(r.a,28) ^ S(r.a,34) ^ S(r.a,39) ) +	(= Sum0(a))
			( (r.a & r.b) ^ (r.a & r.c) ^ (r.b & r.c) );			(= Maj(a,b,c)) */

		S_l( &T2, &r.a, 28 );
		S_h( &T3, &r.a, 34 & (32-1) );
		xor( &T2, &T3 );
		S_h( &T3, &r.a, 39 & (32-1) );
		xor( &T2, &T3 );				/* T2 = Sum0(a) */

		T3 = r.b;
		and( &T3, &r.a );
		T4 = r.c;
		and( &T4, &r.a );
		xor( &T3, &T4 );
		T4 = r.b;
		and( &T4, &r.c );
		xor( &T3, &T4 );					/* T3 = Maj(a,b,c) */

		add( &T2, &T3 );

		r.h = r.g;
		r.g = r.f;
		r.f = r.e;
		r.e = r.d;	add( &r.e, &T1 );
		r.d = r.c;
		r.c = r.b;
		r.b = r.a;
		r.a = T1;	add( &r.a, &T2 );

/*#ifdef SHA512_TEST
		printf( "[%02d] ", t );
		SHA512_PRINT(&r);
#endif*/

	}

	/* finally, add new registers to old; result becomes new hash */

	/* unroll this loop */
	add( &H->a, &r.a );
	add( &H->b, &r.b );
	add( &H->c, &r.c );
	add( &H->d, &r.d );
	add( &H->e, &r.e );
	add( &H->f, &r.f );
	add( &H->g, &r.g );
	add( &H->h, &r.h );

/*	SHA512_PRINT(H); */
}

/* processes up to 1024 bit message block M, output is a 512 bit hash in H. 
   Words in M are big endian. 
   Exact length of M in bytes is in 'length'. 
   Total hashed length is in total_length, also in bytes. 
   Length is expected to always be even to 8 bit (because we work with bytes) 
*/
static void sha512_finalize( SHA512_REGS * const H, 
					 const sha512_message M[] /* points to double size buffer */, 
					 unsigned length, sha512_length * const total_length )  
{
	int padding_length;
	unsigned two=0;

	pgpAssert( length < 1024/8 );

	((PGPByte *)M)[length] = 0x80;

	/* padding_length = block size - length(M) - length(10000000b) - length(total_length) */
	padding_length = 1024/8 - length - 1 - 128/8;

	if( padding_length < 0 ) { 	/* extra block */
		padding_length += 1024/8;
		two = 1;
	}

	memset( (PGPByte *)M+length+1, 0, padding_length );

	sha512Mul8( total_length );	/* total_length *= 8 */

	swap_sha512_word( (sha512_word *)((PGPByte *)M+length+1+padding_length), &total_length->high );
	swap_sha512_word( (sha512_word *)((PGPByte *)M+length+1+padding_length)+1, &total_length->low );

	sha512_process( H, M );
	if( two )
		sha512_process( H, M+1 );

	sha256WordSwapInPlace( (sha512_word*)H, sizeof(*H)/sizeof(sha512_word) );
}


typedef struct PGPSHA512Context_
{
	sha512_message M[2];/* partial message block */
	SHA512_REGS H;		/* SHA-512 registers */
	sha512_length l;	/* 128 bit length */
} PGPSHA512Context;

/* Initialize the SHA values */
static void
pgpSHA384Init(void *priv)
{
	PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
	memset( ctx, 0, sizeof(*ctx) );
	sha384_init( &(ctx->H) );
}
static void
pgpSHA512Init(void *priv)
{
	PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
	memset( ctx, 0, sizeof(*ctx) );
	sha512_init( &(ctx->H) );
}


/* Update SHA for a block of data. */
static void
pgpSHA384_512Update( void *priv, void const *bufIn, PGPSize len)
{
	PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
	unsigned const old_tail= (unsigned)(ctx->l.low.low & (1024/8 - 1));

	unsigned blocks;
	unsigned tail;
	unsigned i;

	const PGPByte *buf = bufIn;

	sha512Add( &(ctx->l), len );		/* first, update number of processed bytes */

	i = sizeof(sha512_message)-old_tail;	/* bytes to add to the message block */

	if( i>len )  {	/* still have no complete block */
		memcpy( ((PGPByte*)ctx->M) + old_tail, buf, len );
		return;
	}

	if( old_tail ) {
		memcpy( ((PGPByte*)ctx->M) + old_tail, buf, i );
		buf += i;
		len -= i;

		sha512_process( &(ctx->H), (const sha512_message*)ctx->M );
	}
	
	blocks =  len / (1024/8);
	tail = len & (1024/8 - 1);

	for( i=0; i<blocks; i++ )  
		sha512_process( &(ctx->H), ((const sha512_message*)buf)+i );

	if( tail )
		memcpy( ctx->M, ((const sha512_message*)buf)+blocks, tail );
}

#ifdef SHA512_TEST
/* prints SHA-512 result after pgpSHA384_512Finalize was called, or 
   prints intermediate SHA-512 registers */
static void pgpSHA512Print( PGPSHA512Context *ctx )  {
	sha512_print( &(ctx->H) );
}
#endif

static void const *
pgpSHA384_512Finalize(void *priv)
{
	PGPSHA512Context *ctx = (PGPSHA512Context *)priv;
	sha512_finalize( &(ctx->H), (const sha512_message *)ctx->M,
		(unsigned)(ctx->l.low.low & (1024/8 - 1)), &(ctx->l) );
	return &(ctx->H);
}

/*
 * SHA384 has an OID of 2.16.840.1.101.3.4.2.2
 * SHA512 has an OID of 2.16.840.1.101.3.4.2.3 
 * From draft-ietf-openpgp-rfc2440bis-03.txt
 */
static PGPByte const SHA384DERprefix[] = {
	0x30, /* Universal, Constructed, Sequence */
	0x41, /* Length 65 (bytes following) */
		0x30, /* Universal, Constructed, Sequence */
		0x0d, /* Length 13 */
			0x06, /* Universal, Primitive, object-identifier */
			0x09, /* Length 9 */
				96, /* 96 = ISO(2)*40 + 16 */
				0x86, 0x48,
				1,
				101,
				3,
				4,
				2,
				2,
			0x05, /* Universal, Primitive, NULL */
			0x00, /* Length 0 */
		0x04,	/* Universal, Primitive, Octet string */
		0x30	/* Length 48 */
				/* 48 SHA384 digest bytes go here */
};
static PGPByte const SHA512DERprefix[] = {
	0x30, /* Universal, Constructed, Sequence */
	0x51, /* Length 81 (bytes following) */
		0x30, /* Universal, Constructed, Sequence */
		0x0d, /* Length 13 */
			0x06, /* Universal, Primitive, object-identifier */
			0x09, /* Length 9 */
				96, /* 96 = ISO(2)*40 + 16 */
				0x86, 0x48,
				1,
				101,
				3,
				4,
				2,
				3,
			0x05, /* Universal, Primitive, NULL */
			0x00, /* Length 0 */
		0x04,	/* Universal, Primitive, Octet string */
		0x40	/* Length 64 */
				/* 64 SHA512 digest bytes go here */
};

PGPHashVTBL const HashSHA384 = {
	"SHA384", kPGPHashAlgorithm_SHA384,
	SHA384DERprefix, sizeof(SHA384DERprefix),
	384/8,
	1024/8, 
	sizeof(PGPSHA512Context),
	sizeof(struct{char _a; PGPSHA512Context _b;}) -
		sizeof(PGPSHA512Context),
	pgpSHA384Init, pgpSHA384_512Update, pgpSHA384_512Finalize
};

PGPHashVTBL const HashSHA512 = {
	"SHA512", kPGPHashAlgorithm_SHA512,
	SHA512DERprefix, sizeof(SHA512DERprefix),
	512/8,
	1024/8,
	sizeof(PGPSHA512Context),
	sizeof(struct{char _a; PGPSHA512Context _b;}) -
		sizeof(PGPSHA512Context),
	pgpSHA512Init, pgpSHA384_512Update, pgpSHA384_512Finalize
};


#ifdef SHA512_TEST
static void test(unsigned is384)  {
	unsigned i,j;
	time_t t;

	PGPByte test1[] = "abc";
	PGPByte test2[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
						"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
	PGPByte test3[sizeof(sha512_message)];

	PGPSHA512Context ctx;

	printf("Beginning SHA %s test\n", is384 ? "384" : "512");

	is384 ? pgpSHA384Init( &ctx ) :	pgpSHA512Init( &ctx );
	pgpSHA384_512Update( &ctx, test1, sizeof(test1)-1 );
	pgpSHA384_512Finalize( &ctx );
	pgpSHA512Print( &ctx );

	is384 ? pgpSHA384Init( &ctx ) :	pgpSHA512Init( &ctx );
	pgpSHA384_512Update( &ctx, test2, sizeof(test2)-1 );
	pgpSHA384_512Finalize( &ctx );
	pgpSHA512Print( &ctx );

	memset(test3, 'a', sizeof(test3));
	t = time(NULL);
	for(j=0; j<1; j++ )  {
		is384 ? pgpSHA384Init( &ctx ) :	pgpSHA512Init( &ctx );
		for( i=1000000; i>=sizeof(test3); i-=sizeof(test3) )
			pgpSHA384_512Update( &ctx, test3, sizeof(test3) );
		pgpSHA384_512Update( &ctx, test3, i );
		pgpSHA384_512Finalize( &ctx );
	}
	printf( "%d sec\n", time(NULL)-t );

	pgpSHA512Print( &ctx );
}

void main()  {
	test(1);
	test(0);

	getchar();
}

#endif

#endif /* PGP_HAVE64 ] */

⌨️ 快捷键说明

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