?? ripemd.c
字號(hào):
/******************************************************************************//* *//* Functions for arithmetic and number theory with large integers in C *//* Software supplement to the book "Cryptography in C and C++" *//* by Michael Welschenbach *//* *//* Module ripemd.c Revision: 16.05.2002 *//* *//* Copyright (C) 1998-2003 by Michael Welschenbach *//* Copyright (C) 2001-2003 by Springer-Verlag Berlin, Heidelberg *//* Copyright (C) 2001-2003 by Apress L.P., Berkeley, CA *//* Copyright (C) 2002-2003 by Wydawnictwa MIKOM, Poland *//* Copyright (C) 2002-2003 by PHEI, P.R.China *//* Copyright (C) 2002-2003 by InfoBook, Korea *//* Copyright (C) 2002-2003 by Triumph Publishing, Russia *//* *//* All Rights Reserved *//* *//* The software may be used for noncommercial purposes and may be altered, *//* as long as the following conditions are accepted without any *//* qualification: *//* *//* (1) All changes to the sources must be identified in such a way that the *//* changed software cannot be misinterpreted as the original software. *//* *//* (2) The statements of copyright may not removed or altered. *//* *//* (3) The following DISCLAIMER is accepted: *//* *//* DISCLAIMER: *//* *//* There is no warranty for the software contained on this CD-ROM, to the *//* extent permitted by applicable law. The copyright holders provide the *//* software `as is' without warranty of any kind, either expressed or *//* implied, including, but not limited to, the implied warranty of fitness *//* for a particular purpose. The entire risk as to the quality and *//* performance of the program is with you. *//* *//* In no event unless required by applicable law or agreed to in writing *//* will the copyright holders, or any of the individual authors named in *//* the source files, be liable to you for damages, including any general, *//* special, incidental or consequential damages arising out of any use of *//* the software or out of inability to use the software (including but not *//* limited to any financial losses, loss of data or data being rendered *//* inaccurate or losses sustained by you or by third parties as a result of *//* a failure of the software to operate with any other programs), even if *//* such holder or other party has been advised of the possibility of such *//* damages. *//* *//******************************************************************************/#include <stdio.h>#include <string.h>#include "flint.h"#include "ripemd.h"#ifndef inline#if (_MSC_VER >= 1100) || defined __GNUC__#define inline __inline#endif#endif/* Prototypes of local functions */static void appetize (ULONG *);static void swallow (ULONG *, ULONG *);static void digest (ULONG *, UCHAR *, ULONG[]);static void appetize128 (ULONG *);static void swallow128 (ULONG *, ULONG *);static void digest128 (ULONG *, UCHAR *, ULONG[]);#ifdef FLINT_SECUREstatic inline void ZeroUlong (ULONG *);static inline void Zero2Ulong (ULONG *, ULONG *);static inline void Zero4Ulong (ULONG *, ULONG *, ULONG *, ULONG *);static inline void ZeroUcharArray (void *, size_t);#endif/* Macros *//* Rotation, simulation of assembler instruction for barrel shifting */#define ROL(X, N) (((X) << (N)) | ((X) >> (32-(N))))/* RIPEMD specific chaining of intermediate values in rounds */#define CHAIN128(A, B, C, D, X, S) { \ (A) = (D); (D) = (C); (C) = (B); \ (B) = ROL((X), (S)); \ }#define CHAIN160(A, B, C, D, E, X, S) { \ (A) = (E); (E) = (D); (D) = ROL((C), 10); (C) = (B); \ (B) = ROL((X), (S)) + (A); \ }/* Conversion of an array of type UCHAR into a value of type ULONG */#if defined LITTLE_ENDIAN#define UC2UL(ucptr) *(unsigned long *)((ucptr))#else#define UC2UL(ucptr) \ (((unsigned long) *((ucptr)+3) << 24) | \ ((unsigned long) *((ucptr)+2) << 16) | \ ((unsigned long) *((ucptr)+1) << 8) | \ ((unsigned long) *(ucptr)))#endif/* Addition of a single-digit number b to a double-digit number represented *//* by an array (a[1],a[0]). A carry in a[0]+=b is handled by increasing a[1]. */#define ADDC(a, b) { \ if (((a)[0] + (b)) < (a)[0]) {(a)[1]++;} \ (a)[0] += (b); \ }/* Constants *//* Choice of message words... */static const intr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13};/* ... for parallel rounds */static const intr2[] = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11};/* Length of rotations... */static const ints1[] = {11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6};/* ... for parallel rounds */static const ints2[] = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11};/*****************************************************************************//* RIPEMD-160 API *//*****************************************************************************//******************************************************************************//* *//* Function: Hashing of a message of length byte in a single step *//* Syntax: void ripemd160 (UCHAR *HashRes, UCHAR *clear, ULONG length); *//* Input: UCHAR *clear (Pointer to message block) *//* ULONG length (Length of message block) *//* Output: UCHAR *HashRes (Hash Value) *//* Returns: - *//* *//******************************************************************************/void __FLINT_APIripemd160 (UCHAR *HashRes, UCHAR *clear, ULONG length){ RMDSTAT hws; ripeinit (&hws); ripefinish (HashRes, &hws, clear, length);#ifdef FLINT_SECURE ZeroUcharArray (&hws, sizeof (hws));#endif /* FLINT_SECURE */ return;}/******************************************************************************//* Functions for blockwise hashing a message in several steps *//* Procedure: Initialization with ripeinit *//* Hashing of block1, block2,... ,blockn with function ripehash *//* Finish operation with function ripefinish *//******************************************************************************//******************************************************************************//* *//* Function: Initialization of RIPEMD-160 function *//* Syntax: void ripeinit (RMDSTAT *hws); *//* Input: RMDSTAT *hws (RIPEMD status buffer) *//* Output: - *//* Returns: - *//* *//******************************************************************************/void __FLINT_APIripeinit (RMDSTAT *hws){ appetize (hws->stomach); hws->total[0] = 0; hws->total[1] = 0;}/******************************************************************************//* *//* Function: Hashing of a message block *//* Syntax: int ripehash (RMDSTAT *hws, UCHAR *clear, ULONG length); *//* Input: RMDSTAT *hws (RIPEMD status buffer) *//* UCHAR *clear (Pointer to message block) *//* ULONG length (Length of message block i bytes = 0 mod 64) *//* Output: - *//* Returns: E_CLINT_OK if everything is O.K. *//* E_CLINT_RMD if length != 0 mod 64 *//* *//******************************************************************************/int __FLINT_APIripehash (RMDSTAT *hws, UCHAR *clear, ULONG length){ ULONG ULBlock[16]; /* message block holding 16 values of type ULONG */ ULONG noofblocks; /* Number of blocks of 16 ULONG-vyluse */ ULONG i, j; /* Counter */ /* If incomplete 64 byte block exists... */ if (length & 63) { return E_CLINT_RMD; /* ...return error code */ } /* Number of 64 byte message blocks in clear */ noofblocks = length >> 6; /* Process 64 byte message blocks in clear */ for (i = 0; i < noofblocks; i++) { for (j = 0; j < 16; j++) { ULBlock[j] = UC2UL (clear); clear += 4; } swallow (hws->stomach, ULBlock); } /* Add length of message in clear to hws->total */ ADDC (hws->total, length);#ifdef FLINT_SECURE /* Overwrite temporary variables */ Zero4Ulong (&ULBlock[0], &ULBlock[1], &ULBlock[2], &ULBlock[3]); Zero4Ulong (&ULBlock[4], &ULBlock[5], &ULBlock[6], &ULBlock[7]); Zero4Ulong (&ULBlock[8], &ULBlock[9], &ULBlock[10], &ULBlock[11]); Zero4Ulong (&ULBlock[12], &ULBlock[13], &ULBlock[14], &ULBlock[15]);#endif return E_CLINT_OK;}/******************************************************************************//* *//* Function: Finish hash function RIPEMD-160 *//* Syntax: void ripefinish (UCHAR *HashRes, RMDSTAT *hws, UCHAR *clear, *//* ULONG length); *//* Input: RMDSTAT *hws (RIPEMD status buffer) *//* UCHAR *clear (Pointer to the last message block *//* ULONG length (Length of message block in bytes) *//* Output: UCHAR HashRes (20 byte hash value) *//* Returns: - *//* *//******************************************************************************/void __FLINT_APIripefinish (UCHAR *HashRes, RMDSTAT *hws, UCHAR *clear, ULONG length){ unsigned i; /* Number of bytes in complete blocks */ ULONG blength = (length >> 6) << 6; /* Process complete blocks in clear */ ripehash (hws, clear, blength); /* Add length of message in clear to hws->total */ ADDC (hws->total,length - blength); /* Process last incomplete block with padding and length of message */ digest (hws->stomach, clear + blength, hws->total); for (i = 0; i < 20; i += 4)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -