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

📄 pgpripemd160.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
{
   PGPUInt32        i;                          /* counter       */
   PGPUInt32        X[16];                      /* message words */

   pgpClearMemory( X,  16*sizeof(PGPUInt32));

   /* put bytes from strptr into X */
   for (i=0; i<(lswlen&63); i++) {
      /* byte i goes into word X[i div 4] at pos.  8*(i mod 4)  */
      X[i>>2] ^= (PGPUInt32) *strptr++ << (8 * (i&3));
   }

   /* append the bit m_n == 1 */
   X[(lswlen>>2)&15] ^= (PGPUInt32)1 << (8*(lswlen&3) + 7);

   if ((lswlen & 63) > 55) {
      /* length goes to next block */
      RMDcompress(MDbuf, X);
	  pgpClearMemory( X,  16*sizeof(PGPUInt32));
   }

   /* append length in bits*/
   X[14] = lswlen << 3;
   X[15] = (lswlen >> 29) | (mswlen << 3);
   RMDcompress(MDbuf, X);

   return;
}

/************************ end of file rmd160.c **********************/
/* Remainder provides common interface used by PGP library */


/*
 * Shuffle the bytes into little-endian order within 32-bit words,
 * as per the RIPEMD-160 spec (which follows MD4 conventions).
 */
static void
rmd160ByteSwap(PGPUInt32 *dest, PGPByte const *src, unsigned words)
{
	do {
		*dest++ = (PGPUInt32)((unsigned)src[3] << 8 | src[2]) << 16 |
		                  ((unsigned)src[1] << 8 | src[0]);
		src += 4;
	} while (--words);
}


/* Initialize the RIPEMD-160 values */

static void
rmd160Init(void *priv)
{
	struct RIPEMD160Context *ctx = (struct RIPEMD160Context *)priv;

	/* Set the h-vars to their initial values */
	RMDinit (ctx->iv);

	/* Initialise bit count */
	ctx->bytesHi = 0;
	ctx->bytesLo = 0;
}

/* Update the RIPEMD-160 hash state for a block of data. */

static void
rmd160Update(void *priv, void const *bufIn, PGPSize len)
{
	struct RIPEMD160Context *ctx = (struct RIPEMD160Context *)priv;
	unsigned i;
	PGPByte *buf = (PGPByte *) bufIn;
	
	/* Update bitcount */

	PGPUInt32 t = ctx->bytesLo;
	if ( ( ctx->bytesLo = t + len ) < t )
		ctx->bytesHi++;	/* Carry from low to high */

	i = (unsigned)t % RIPEMD160_BLOCKBYTES; /* bytes already in ctx->key */

	/* i is always less than RIPEMD160_BLOCKBYTES. */
	if (RIPEMD160_BLOCKBYTES-i > len) {
		pgpCopyMemory(buf, (PGPByte *)ctx->key + i, len);
		return;
	}

	if (i) {	/* First chunk is an odd size */
		pgpCopyMemory(buf, (PGPByte *)ctx->key + i, RIPEMD160_BLOCKBYTES - i);
		rmd160ByteSwap(ctx->key, (PGPByte *)ctx->key, RIPEMD160_BLOCKWORDS);
		RMDcompress(ctx->iv, ctx->key);
		buf += RIPEMD160_BLOCKBYTES-i;
		len -= RIPEMD160_BLOCKBYTES-i;
	}

	/* Process data in 64-byte chunks */
	while (len >= RIPEMD160_BLOCKBYTES) {
		rmd160ByteSwap(ctx->key, buf, RIPEMD160_BLOCKWORDS);
		RMDcompress(ctx->iv, ctx->key);
		buf += RIPEMD160_BLOCKBYTES;
		len -= RIPEMD160_BLOCKBYTES;
	}

	/* Handle any remaining bytes of data. */
	if (len)
		pgpCopyMemory(buf, ctx->key, len);
}


/* Final wrapup - MD4 style padding on last block. */

static void const *
rmd160Final(void *priv)
{
	struct RIPEMD160Context *ctx = (struct RIPEMD160Context *)priv;
	PGPByte *digest;
	int i;
	PGPUInt32 t;

	RMDfinish(ctx->iv, (PGPByte *)ctx->key, ctx->bytesLo, ctx->bytesHi);

	digest = (PGPByte *)ctx->iv;
	for (i = 0; i < RIPEMD160_HASHWORDS; i++) {
		t = ctx->iv[i];
		digest[0] = (PGPByte)t;
		digest[1] = (PGPByte)(t >> 8);
		digest[2] = (PGPByte)(t >> 16);
		digest[3] = (PGPByte)(t >> 24);
		digest += 4;
	}
	/* In case it's sensitive */
/* XXX   pgpClearMemory( ctx, sizeof(ctx)); */

	return (PGPByte const *)ctx->iv;
}



/*
 * RIPEM OID is 1.3.36.3.2.1, from URL above.
 * The rest of the format is stolen from MD5.  Do we need the NULL
 * in there?
 */
static PGPByte const RIPEMD160DERprefix[] = {
	0x30, /* Universal, Constructed, Sequence */
	0x21, /* Length 33 (bytes following) */
		0x30, /* Universal, Constructed, Sequence */
		0x09, /* Length 9 */
			0x06, /* Universal, Primitive, object-identifier */
			0x05, /* Length 8 */
				43, /* 43 = ISO(1)*40 + 3 */
				36,
				3,
				2,
				1,
			0x05, /* Universal, Primitive, NULL */
			0x00, /* Length 0 */
		0x04, /* Universal, Primitive, Octet string */
		0x14 /* Length 20 */
			/* 20 RIPEMD-160 digest bytes go here */
};

struct PGPHashVTBL const HashRIPEMD160 = {
	"RIPEMD160", kPGPHashAlgorithm_RIPEMD160,
	RIPEMD160DERprefix, sizeof(RIPEMD160DERprefix),
	RIPEMD160_HASHBYTES,
	sizeof(struct RIPEMD160Context),
	sizeof(struct{char _a; struct RIPEMD160Context _b;}) -
		sizeof(struct RIPEMD160Context),
	rmd160Init, rmd160Update, rmd160Final
};


#if TESTMAIN

/* --------------------------- RMD160 Test code --------------------------- */
#include <stdio.h>
#include <stdlib.h>	/* For exit() */
#include <time.h>

/* Size of buffer for RMD160 speed test data */

#define TEST_BLOCK_SIZE	( RIPEMD160_HASHBYTES * 100 )

/* Number of bytes of test data to process */

#define TEST_BYTES	10000000L
#define TEST_BLOCKS	( TEST_BYTES / TEST_BLOCK_SIZE )

static char const *rmd160TestResults[] = {
	"9C1185A5C5E9FC54612808977EE8F548B2258D31",		/* "" */
	"0BDC9D2D256B3EE9DAAE347BE6F4DC835A467FFE",		/* "a" */
	"8EB208F7E05D987A9B044A8E98C6B087F15A0BFC",		/* "abc" */
	"5D0689EF49D2FAE572B881B123A85FFA21595F36",		/* "message digest" */
	"F71C27109C692C1B56BBDCEB5B9D2865B3708DBC",		/* "a..z" */
	"12A053384A9C0C88E405A06C27DCF49ADA62EB2B",		/* "abcdbcde...nopq" */
	"B0E20B6E3116640286ED3A87A5713079B21F5189",		/* "A..Za..z0..9" */
	"9B752E45573D4B39F4DBD3323CAB82BF63326BFB",		/* 8 * "1234567890" */
	"52783243C1697BDBE16D37F97F68F08325DC1528",		/* 1,000,000 "a" */
	"52783243C1697BDBE16D37F97F68F08325DC1528",		/* 1,000,000 "a" */
	"52783243C1697BDBE16D37F97F68F08325DC1528" };	/* 1,000,000 "a" */

static int
compareRMD160results(PGPByte const *hash, int level)
{
	char buf[41];
	int i;

	for (i = 0; i < RIPEMD160_HASHBYTES; i++)
		sprintf(buf+2*i, "%02X", hash[i]);

	if (strcmp(buf, rmd160TestResults[level-1]) == 0) {
		printf("Test %d passed, result = %s\n", level, buf);
		return 0;
	} else {
		printf("Error in RMD160 implementation: Test %d failed\n", level);
		printf("  Result = %s\n", buf);
		printf("Expected = %s\n", rmd160TestResults[level-1]);
		return -1;
	}
}


int
main(void)
{
	struct RIPEMD160Context rmd160;
	PGPByte data[TEST_BLOCK_SIZE];
	PGPByte const *hash;
	clock_t ticks;
	long i;

	/*
	 * Test output data, based on URL above.
	 */
	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"", 0);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 1) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"a", 1);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 2) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"abc", 3);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 3) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"message digest", 14);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 4) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"abcdefghijklmnopqrstuvwxyz", 26);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 5) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"abcdbcdecdefdefgefghfghighijhijkijkl\
jklmklmnlmnomnopnopq", 56);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 6) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz0123456789", 62);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 7) < 0)
		exit (-1);

	rmd160Init(&rmd160);
	rmd160Update(&rmd160, (PGPByte *)"123456789012345678901234567890\
12345678901234567890123456789012345678901234567890", 80);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 8) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 64's */
	rmd160Init(&rmd160);
	for (i = 0; i < 15625; i++)
		rmd160Update(&rmd160, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 9) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 25's */
	rmd160Init(&rmd160);
	for (i = 0; i < 40000; i++)
		rmd160Update(&rmd160, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 10) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 125's */
	rmd160Init(&rmd160);
	for (i = 0; i < 8000; i++)
		rmd160Update(&rmd160, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125);
	hash = rmd160Final(&rmd160);
	if (compareRMD160results(hash, 11) < 0)
		exit (-1);

	/* Now perform time trial, generating MD for 10MB of data.  First,
	   initialize the test data */
	pgpClearMemory( data,  TEST_BLOCK_SIZE);

	/* Get start time */
	printf("RMD160 time trial.  Processing %ld characters...\n", TEST_BYTES);
	ticks = clock();

	/* Calculate RMD160 message digest in TEST_BLOCK_SIZE byte blocks */
	rmd160Init(&rmd160);
	for (i = TEST_BLOCKS; i > 0; i--)
		rmd160Update(&rmd160, data, TEST_BLOCK_SIZE);
	hash = rmd160Final(&rmd160);

	/* Get finish time and print difference */
	ticks = clock() - ticks;
	printf("Ticks to process test input: %lu\n", (unsigned long)ticks);

	return 0;
}
#endif /* Test driver */

⌨️ 快捷键说明

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