Files
Justin Marshall 101266ab72 Initial commit.
2026-04-27 10:35:40 -07:00

190 lines
4.9 KiB
C++

/****************************************************************************
*
* SHA.CPP
* Secure Hash Algorithm
*
* Implementation copyright (C) 1995, Michael O'Brien. All rights reserved.
*
* key size - N/A
* input block size - 512 bits
* output block size - 160 bits
*
***/
#include "diablo.h"
#pragma hdrstop
//******************************************************************
//******************************************************************
#define SHA_BLOCKSIZE 64
#define SHA_DIGESTSIZE 20
#define F1(x,y,z) ((x & y) | (~x & z))
#define F2(x,y,z) (x ^ y ^ z)
#define F3(x,y,z) ((x & y) | (x & z) | (y & z))
#define F4(x,y,z) (x ^ y ^ z)
#define K1 0x5A827999
#define K2 0x6ED9EBA1
#define K3 0x8f1BBCDC
#define K4 0xCA62C1D6
#define H0INIT 0x67452301
#define H1INIT 0xEFCDAB89
#define H2INIT 0x98BADCFE
#define H3INIT 0x10325476
#define H4INIT 0xC3D2E1F0
#define S(n,x) ((x << n) | (x >> (32 - n)))
#define EXPAND(c) w[c] = w[c-3] ^ w[c-8] ^ w[c-14] ^ w[c-16]
#define SUBROUND1(num) temp = S(5,a) + F1(b,c,d) + e + w[num] + K1
#define SUBROUND2(num) temp = S(5,a) + F2(b,c,d) + e + w[num] + K2
#define SUBROUND3(num) temp = S(5,a) + F3(b,c,d) + e + w[num] + K3
#define SUBROUND4(num) temp = S(5,a) + F4(b,c,d) + e + w[num] + K4
typedef struct _shainfo {
int digest[5];
int countlo;
int counthi;
int data[16];
} shainfo, *shainfoptr;
//******************************************************************
//******************************************************************
static void InitializeHash (shainfoptr infoptr) {
infoptr->digest[0] = H0INIT;
infoptr->digest[1] = H1INIT;
infoptr->digest[2] = H2INIT;
infoptr->digest[3] = H3INIT;
infoptr->digest[4] = H4INIT;
infoptr->countlo = 0;
infoptr->counthi = 0;
}
//******************************************************************
//******************************************************************
static void TransformHash (shainfoptr infoptr) {
int w[80];
int loop;
for (loop = 0; loop < 16; loop++)
w[loop] = infoptr->data[loop];
for (loop = 16; loop < 80; loop++)
EXPAND(loop);
int a = infoptr->digest[0];
int b = infoptr->digest[1];
int c = infoptr->digest[2];
int d = infoptr->digest[3];
int e = infoptr->digest[4];
int temp;
for (loop = 0; loop < 20; loop++) {
SUBROUND1(loop);
e = d;
d = c;
c = S(30,b);
b = a;
a = temp;
}
for (loop = 20; loop < 40; loop++) {
SUBROUND2(loop);
e = d;
d = c;
c = S(30,b);
b = a;
a = temp;
}
for (loop = 40; loop < 60; loop++) {
SUBROUND3(loop);
e = d;
d = c;
c = S(30,b);
b = a;
a = temp;
}
for (loop = 60; loop < 80; loop++) {
SUBROUND4(loop);
e = d;
d = c;
c = S(30,b);
b = a;
a = temp;
}
infoptr->digest[0] += a;
infoptr->digest[1] += b;
infoptr->digest[2] += c;
infoptr->digest[3] += d;
infoptr->digest[4] += e;
for (loop = 0; loop < 80; loop++)
w[loop] = 0;
a = b = c = d = e = 0;
}
//******************************************************************
//******************************************************************
static void UpdateHash (shainfoptr infoptr, const BYTE *buffer, int bytes) {
if ((infoptr->countlo + (bytes << 3)) < infoptr->countlo)
infoptr->counthi++;
infoptr->countlo += bytes << 3;
infoptr->counthi += bytes >> 29;
while (bytes >= SHA_BLOCKSIZE) {
CopyMemory(infoptr->data,buffer,SHA_BLOCKSIZE);
TransformHash(infoptr);
buffer += SHA_BLOCKSIZE;
bytes -= SHA_BLOCKSIZE;
}
}
/****************************************************************************
*
* EXPORTED FUNCTIONS
*
***/
static shainfo currinfo[3];
//******************************************************************
//******************************************************************
void ShaDestroy () {
ZeroMemory(&currinfo,3*sizeof(shainfo));
}
//******************************************************************
//******************************************************************
void ShaGetLastHash (int streamnum, void *outptr) {
if (outptr) {
DWORD *outptr32 = (DWORD *)outptr;
int loop = 0;
while (loop < 5)
*(outptr32++) = currinfo[streamnum].digest[loop++];
}
}
//******************************************************************
//******************************************************************
void ShaHash (int streamnum, const void *inptr, void *outptr) {
UpdateHash(&currinfo[streamnum],(const BYTE *)inptr,SHA_BLOCKSIZE);
if (outptr)
ShaGetLastHash(streamnum,outptr);
}
//******************************************************************
//******************************************************************
void ShaInitialize (int streamnum) {
InitializeHash(&currinfo[streamnum]);
}