#include <malloc.h>
#include <stdlib.h>
#pragma intrinsic(_lrotl)
#define RolX(x,y)   _lrotl(x,y)
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
#define FF(A, B, C, D, X, S, AC) A = _lrotl(A + ((B & C) | (~B & D)) + X + AC, S) + B
#define GG(A, B, C, D, X, S, AC) A = _lrotl(A + ((B & D) | (C & ~D)) + X + AC, S) + B
#define HH(A, B, C, D, X, S, AC) A = _lrotl(A + (B ^ C ^ D) + X + AC, S) + B
#define II(A, B, C, D, X, S, AC) A = _lrotl(A + (C ^ (B | ~D)) + X + AC, S) + B

void HashMD5(unsigned char* Digest, char* Buf, ULONG BufSize);


/* PROTOTYPES should be set to one if and only if the compiler supports
     function argument prototyping.
   The following makes PROTOTYPES default to 0 if it has not already
     been defined with C compiler flags.
 */
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif

/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;

/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;

/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;

/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
   rights reserved.

   License to copy and use this software is granted for
   non-commercial Internet Privacy-Enhanced Mail provided that it is
   identified as the "RSA Data Security, Inc. MD2 Message Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   RSA Data Security, Inc. 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.
 */

typedef struct {
  unsigned char state[16];                                 /* state */
  unsigned char checksum[16];                           /* checksum */
  unsigned int count;                 /* number of bytes, modulo 16 */
  unsigned char buffer[16];                         /* input buffer */
} MD2_CTX;

void MD2Init(MD2_CTX *);
void MD2Update(MD2_CTX *, unsigned char *, unsigned int);
void MD2Final(unsigned char [16], MD2_CTX *);

void HashMD2(unsigned char* Digest, char* Buf, ULONG BufSize);
