Devilution
Diablo devolved - magic behind the 1996 computer game
sha.cpp
Go to the documentation of this file.
1 #include "all.h"
2 
3 #include <cstdint>
4 
6 
7 // NOTE: Diablo's "SHA1" is different from actual SHA1 in that it uses arithmetic
8 // right shifts (sign bit extension).
9 
10 namespace {
11 
12 /*
13  * Diablo-"SHA1" circular left shift, portable version.
14  */
15 std::uint32_t SHA1CircularShift(std::uint32_t bits, std::uint32_t word) {
16  assert(bits < 32);
17  assert(bits > 0);
18 
19  if(word >> 31) {
20  return (word << bits) | (~((~word) >> (32 - bits)));
21  } else {
22  return (word << bits) | (word >> (32 - bits));
23  }
24 }
25 
26 } // namespace
27 
29 
30 void SHA1Clear()
31 {
32  memset(sgSHA1, 0, sizeof(sgSHA1));
33 }
34 
35 void SHA1Result(int n, char Message_Digest[SHA1HashSize])
36 {
37  DWORD *Message_Digest_Block;
38  int i;
39 
40  Message_Digest_Block = (DWORD *)Message_Digest;
41  if (Message_Digest) {
42  for (i = 0; i < 5; i++) {
43  *Message_Digest_Block = SwapLE32(sgSHA1[n].state[i]);
44  Message_Digest_Block++;
45  }
46  }
47 }
48 
49 void SHA1Calculate(int n, const char *data, char Message_Digest[SHA1HashSize])
50 {
51  SHA1Input(&sgSHA1[n], data, 64);
52  if (Message_Digest)
53  SHA1Result(n, Message_Digest);
54 }
55 
56 void SHA1Input(SHA1Context *context, const char *message_array, int len)
57 {
58  int i, count;
59 
60  count = context->count[0] + 8 * len;
61  if (count < context->count[0])
62  context->count[1]++;
63 
64  context->count[0] = count;
65  context->count[1] += len >> 29;
66 
67  for (i = len; i >= 64; i -= 64) {
68  memcpy(context->buffer, message_array, sizeof(context->buffer));
69  SHA1ProcessMessageBlock(context);
70  message_array += 64;
71  }
72 }
73 
75 {
76  DWORD i, temp;
77  DWORD W[80];
78  DWORD A, B, C, D, E;
79 
80  DWORD *buf = (DWORD *)context->buffer;
81  for (i = 0; i < 16; i++)
82  W[i] = SwapLE32(buf[i]);
83 
84 
85  for (i = 16; i < 80; i++) {
86  W[i] = W[i - 16] ^ W[i - 14] ^ W[i - 8] ^ W[i - 3];
87  }
88 
89  A = context->state[0];
90  B = context->state[1];
91  C = context->state[2];
92  D = context->state[3];
93  E = context->state[4];
94 
95  for (i = 0; i < 20; i++) {
96  temp = SHA1CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[i] + 0x5A827999;
97  E = D;
98  D = C;
99  C = SHA1CircularShift(30, B);
100  B = A;
101  A = temp;
102  }
103 
104  for (i = 20; i < 40; i++) {
105  temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1;
106  E = D;
107  D = C;
108  C = SHA1CircularShift(30, B);
109  B = A;
110  A = temp;
111  }
112 
113  for (i = 40; i < 60; i++) {
114  temp = SHA1CircularShift(5, A) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC;
115  E = D;
116  D = C;
117  C = SHA1CircularShift(30, B);
118  B = A;
119  A = temp;
120  }
121 
122  for (i = 60; i < 80; i++) {
123  temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6;
124  E = D;
125  D = C;
126  C = SHA1CircularShift(30, B);
127  B = A;
128  A = temp;
129  }
130 
131  context->state[0] += A;
132  context->state[1] += B;
133  context->state[2] += C;
134  context->state[3] += D;
135  context->state[4] += E;
136 }
137 
138 void SHA1Reset(int n)
139 {
140  SHA1Init(&sgSHA1[n]);
141 }
142 
143 void SHA1Init(SHA1Context *context)
144 {
145  context->count[0] = 0;
146  context->count[1] = 0;
147  context->state[0] = 0x67452301;
148  context->state[1] = 0xEFCDAB89;
149  context->state[2] = 0x98BADCFE;
150  context->state[3] = 0x10325476;
151  context->state[4] = 0xC3D2E1F0;
152 }
153 
SHA1Context::buffer
char buffer[64]
Definition: structs.h:1444
SHA1Reset
void SHA1Reset(int n)
Definition: sha.cpp:138
SHA1Context::count
DWORD count[2]
Definition: structs.h:1443
all.h
DEVILUTION_BEGIN_NAMESPACE::SHA1CircularShift
std::uint32_t SHA1CircularShift(std::uint32_t bits, std::uint32_t word)
Definition: sha.cpp:15
assert
#define assert(exp)
Definition: defs.h:168
SHA1Input
void SHA1Input(SHA1Context *context, const char *message_array, int len)
Definition: sha.cpp:56
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
SHA1Calculate
void SHA1Calculate(int n, const char *data, char Message_Digest[SHA1HashSize])
Definition: sha.cpp:49
SHA1ProcessMessageBlock
void SHA1ProcessMessageBlock(SHA1Context *context)
Definition: sha.cpp:74
SHA1Init
void SHA1Init(SHA1Context *context)
Definition: sha.cpp:143
SwapLE32
#define SwapLE32
Definition: defs.h:182
SHA1Result
void SHA1Result(int n, char Message_Digest[SHA1HashSize])
Definition: sha.cpp:35
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
sgSHA1
SHA1Context sgSHA1[3]
Definition: sha.cpp:28
SHA1Clear
void SHA1Clear()
Definition: sha.cpp:30
SHA1Context::state
DWORD state[5]
Definition: structs.h:1442
SHA1Context
Definition: structs.h:1441
SHA1HashSize
#define SHA1HashSize
Definition: sha.h:5