📄 ripemd.c
字号:
/* header files *//********************************************************************\ * FILE: rmd160.c * CONTENTS: A sample C-implementation of the RIPEMD-160 hash-function. * TARGET: any computer with an ANSI C compiler * AUTHOR: Antoon Bosselaers, Dept. Electrical Eng.-ESAT/COSIC * DATE: 1 March 1996 VERSION: 1.0 ********************************************************************** * Copyright (c) Katholieke Universiteit Leuven 1996, All Rights Reserved * The Katholieke Universiteit Leuven makes no representations concerning * either the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" without * express or implied warranty of any kind. These notices must be retained * in any copies of any part of this documentation and/or software.\********************************************************************/#include <string.h>#include "Python.h"#ifdef MS_WIN32#include <winsock2.h>#else#include <sys/param.h>#include <netinet/in.h>#endif#include "Python.h"#define MODULE_NAME RIPEMD#define DIGEST_SIZE 20/********************************************************************//* Macro definitions *//* ROL(x, n) cyclically rotates x over n bits to the left x must be of an unsigned 32 bits type and 0 <= n < 32.*/#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))/* The five basic RIPEMD-160 functions F1(), F2(), F3(), F4(), and F5()*/#define F1(x, y, z) ((x) ^ (y) ^ (z))#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))#define F3(x, y, z) (((x) | ~(y)) ^ (z))#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))#define F5(x, y, z) ((x) ^ ((y) | ~(z)))/* The ten basic RIPEMD-160 transformations FF1() through FFF5()*/#define FF1(a, b, c, d, e, x, s) {\ (a) += F1((b), (c), (d)) + (x);\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FF2(a, b, c, d, e, x, s) {\ (a) += F2((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FF3(a, b, c, d, e, x, s) {\ (a) += F3((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FF4(a, b, c, d, e, x, s) {\ (a) += F4((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FF5(a, b, c, d, e, x, s) {\ (a) += F5((b), (c), (d)) + (x) + 0xa953fd4eUL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FFF1(a, b, c, d, e, x, s) {\ (a) += F1((b), (c), (d)) + (x);\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FFF2(a, b, c, d, e, x, s) {\ (a) += F2((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FFF3(a, b, c, d, e, x, s) {\ (a) += F3((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FFF4(a, b, c, d, e, x, s) {\ (a) += F4((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }#define FFF5(a, b, c, d, e, x, s) {\ (a) += F5((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROL((a), (s)) + (e);\ (c) = ROL((c), 10);\ }typedef unsigned char byte; /* unsigned 8-bit integer */#ifdef __alpha__typedef unsigned int word; /* unsigned 32-bit integer */#elif defined(__amd64__)typedef uint32_t word; /* unsigned 32-bit integer */#elsetypedef unsigned long word; /* unsigned 32-bit integer */#endiftypedef unsigned char BYTE;#define RMD_DATASIZE 64#define RMD_DIGESTSIZE 20#define RMDsize 160typedef struct { word digest[ 5 ]; /* Message digest */ word countLo, countHi; /* 64-bit bit count */ word data[ 16 ]; /* data buffer*/ int nbytes;} hash_state;static void MDinit(word *MDbuf);static void MDcompress(word *MDbuf, word *X);static void MDfinish(hash_state *self);/********************************************************************/static void hash_init(hash_state *rmdInfo)/* Initialization of the 5-word MDbuf array to the magic initialization constants */{ MDinit(rmdInfo->digest); rmdInfo->countLo = rmdInfo->countHi =rmdInfo->nbytes = 0;}static void hash_update(hash_state *shsInfo,char *buffer, int count){ word tmp; int dataCount, i; BYTE *p; /* Update bitcount */ tmp = shsInfo->countLo; if ( ( shsInfo->countLo = tmp + ( ( word ) count << 3 ) ) < tmp ) shsInfo->countHi++; /* Carry from low to high */ shsInfo->countHi += count >> 29; /* Get count of bytes already in data */ dataCount = ( int ) ( tmp >> 3 ) & 0x3F; /* Handle any leading odd-sized chunks */ if(dataCount) { p = ( BYTE * ) shsInfo->data + dataCount; dataCount = RMD_DATASIZE - dataCount; if( count < dataCount ) { memcpy(p, buffer, count); return; } memcpy(p, buffer, dataCount); for(i=0; i<16; i++) { long t = htonl(shsInfo->data[i]); t = ( ((t>>24) & 0xff) + (((t>>16) & 0xff)<<8) + (((t>> 8) & 0xff)<<16) + (((t ) & 0xff)<<24) ); shsInfo->data[i] = t; } MDcompress(shsInfo->digest,shsInfo->data); buffer += dataCount; count -= dataCount; } /* Process data in RMD_DATASIZE chunks */ while( count >= RMD_DATASIZE ) { memcpy( shsInfo->data, buffer, RMD_DATASIZE ); for(i=0; i<16; i++) { long t = htonl(shsInfo->data[i]); t = ( ((t>>24) & 0xff) + (((t>>16) & 0xff)<<8) + (((t>> 8) & 0xff)<<16) + (((t ) & 0xff)<<24) ); shsInfo->data[i] = t; } MDcompress(shsInfo->digest,shsInfo->data); buffer += RMD_DATASIZE; count -= RMD_DATASIZE; } /* Handle any remaining bytes of data. */ memcpy(shsInfo->data, buffer, count);}static PyObject *hash_digest(hash_state *self){ hash_state temp; int i; byte hashcode[RMDsize/8]; /* final hash-value */ temp.countLo=self->countLo; temp.countHi=self->countHi; for(i=0; i<5; i++) temp.digest[i]=self->digest[i]; for(i=0; i<16; i++) temp.data[i]=self->data[i]; MDfinish(&temp); /* Convert word to a string of bytes using a Little-endian convention */ for (i=0; i<RMDsize/8; i+=4) { hashcode[i] = temp.digest[i>>2]; hashcode[i+1] = (temp.digest[i>>2] >> 8); hashcode[i+2] = (temp.digest[i>>2] >> 16); hashcode[i+3] = (temp.digest[i>>2] >> 24); } return PyString_FromStringAndSize(hashcode, RMD_DIGESTSIZE);}static void hash_copy(hash_state *src,hash_state *dest){ int i; dest->countLo=src->countLo; dest->countHi=src->countHi; for(i=0; i<5; i++) dest->digest[i]=src->digest[i]; for(i=0; i<16; i++) dest->data[i]=src->data[i];}/********************************************************************/static void MDinit(word *MDbuf)/* Initialization of the 5-word MDbuf array to the magic initialization constants */{ MDbuf[0] = 0x67452301UL; MDbuf[1] = 0xefcdab89UL; MDbuf[2] = 0x98badcfeUL; MDbuf[3] = 0x10325476UL; MDbuf[4] = 0xc3d2e1f0UL;}/********************************************************************/static void MDcompress(word *MDbuf, word *X)/* The compression function is called for every complete 64-byte message block. The 5-word internal state MDbuf is updated using message words X[0] through X[15]. The conversion from a string of 64 bytes to an array of 16 words using a Little-endian convention is the responsibility of the calling function.*/{ /* make two copies of the old state */ word aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], dd = MDbuf[3], ee = MDbuf[4];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -