The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sha1.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 - 2016 by Benoit Timbert <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Secure Hash Algorithm 1 (SHA-1).
18  * Used to checksum the game-config / cache.
19  */
20 
21 /* This is supposed to be an implementation of the
22  Secure Hash Algorithm 1 (SHA-1)
23 
24  Check RFC 3174 for details about the algorithm.
25 
26  Currently this implementation might produce different results on little-
27  and big-endian machines, but for our current usage, we don't care :)
28 */
29 
30 #include "sha1.hpp"
31 
32 #include <iomanip>
33 #include <sstream>
34 
35 #define sha_rotl(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
36 #define sha_ch(x,y,z) ( ((x) & (y)) | ((~(x)) & (z)) )
37 #define sha_parity(x,y,z) ( (x) ^ (y) ^ (z) )
38 #define sha_maj(x,y,z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
39 
41  std::stringstream s;
42  s << std::hex << std::setfill('0') << std::setw(8) << H0;
43  s << std::hex << std::setfill('0') << std::setw(8) << H1;
44  s << std::hex << std::setfill('0') << std::setw(8) << H2;
45  s << std::hex << std::setfill('0') << std::setw(8) << H3;
46  s << std::hex << std::setfill('0') << std::setw(8) << H4;
47  return s.str();
48 }
49 
51 : H0(0x67452301), H1(0xefcdab89), H2(0x98badcfe), H3(0x10325476), H4(0xc3d2e1f0)
52 {
53  Uint8 block[64];
54 
55  int bytes_left = str.size();
56  Uint32 ssz = bytes_left * 8; // string length in bits
57 
58  std::stringstream iss (str, std::stringstream::in);
59  // cut our string in 64 bytes blocks then process it
60  while (bytes_left > 0) {
61  iss.read(reinterpret_cast<char*>(block), 64);
62  if (bytes_left <= 64) { // if it's the last block, pad it
63  if (bytes_left < 64) {
64  block[bytes_left]= 0x80; // add a 1 bit right after the end of the string
65  }
66  int i;
67  for (i = 63; i > bytes_left; i--) {
68  block[i]=0; // pad our block with zeros
69  }
70  if (bytes_left < 56) { // enough space to store the length
71  // put the length at the end of the block
72  block[60] = ssz >> 24;
73 #ifdef _MSC_VER
74 #pragma warning (push)
75 #pragma warning (disable: 4244)
76 #endif
77  block[61] = ssz >> 16;
78  block[62] = ssz >> 8;
79  block[63] = ssz;
80 #ifdef _MSC_VER
81 #pragma warning (pop)
82 #endif
83  } else { // not enough space for the zeros => we need a new block
84  next(block);
85  // new block
86  for (i = 0; i < 60 ; i++) {
87  block[i]=0; // pad our block with zeros
88  }
89  if (bytes_left == 64) {
90  block[0]= 0x80; // add a 1 bit right after the end of the string = beginning of our new block
91  }
92  // put the length at the end of the block
93  block[60] = ssz >> 24;
94 #ifdef _MSC_VER
95 #pragma warning (push)
96 #pragma warning (disable: 4244)
97 #endif
98  block[61] = ssz >> 16;
99  block[62] = ssz >> 8;
100  block[63] = ssz;
101 #ifdef _MSC_VER
102 #pragma warning (pop)
103 #endif
104  }
105  }
106  next(block);
107  bytes_left -= 64;
108  }
109 }
110 
111 void sha1_hash::next(Uint8 block[64]) {
112  Uint32 W[80];
113  Uint32 A, B, C, D, E, T;
114  int i;
115 
116  A = H0;
117  B = H1;
118  C = H2;
119  D = H3;
120  E = H4;
121  for (i = 0; i < 16; i++) {
122  W[i]= (block[4 * i] << 24) | (block[4 * i + 1] << 16) | (block[4 * i + 2] << 8) | block[4 * i + 3];
123  }
124  for (; i < 80; i++) {
125  W[i]=sha_rotl(1, W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]);
126  }
127  for (i = 0; i < 20; i++) {
128  T = sha_rotl(5,A) + sha_ch(B,C,D) + E + W[i] + 0x5a827999;
129  E = D;
130  D = C;
131  C = sha_rotl(30,B);
132  B = A;
133  A = T;
134  }
135  for (; i < 40; i++) {
136  T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0x6ed9eba1;
137  E = D;
138  D = C;
139  C = sha_rotl(30,B);
140  B = A;
141  A = T;
142  }
143  for (; i < 60; i++) {
144  T = sha_rotl(5,A) + sha_maj(B,C,D) + E + W[i] + 0x8f1bbcdc;
145  E = D;
146  D = C;
147  C = sha_rotl(30,B);
148  B = A;
149  A = T;
150  }
151  for (; i < 80; i++) {
152  T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0xca62c1d6;
153  E = D;
154  D = C;
155  C = sha_rotl(30,B);
156  B = A;
157  A = T;
158  }
159  H0 += A;
160  H1 += B;
161  H2 += C;
162  H3 += D;
163  H4 += E;
164 }
#define sha_parity(x, y, z)
Definition: sha1.cpp:37
Uint32 H1
Definition: sha1.hpp:34
Uint32 H0
Definition: sha1.hpp:34
GLuint in
Definition: glew.h:9261
#define sha_maj(x, y, z)
Definition: sha1.cpp:38
#define sha_rotl(n, x)
Definition: sha1.cpp:35
#define sha_ch(x, y, z)
Definition: sha1.cpp:36
Uint32 H4
Definition: sha1.hpp:34
Uint32 H3
Definition: sha1.hpp:34
std::string display()
Display the hash.
Definition: sha1.cpp:40
void next(Uint8 block[64])
Process the next 512 bits block.
Definition: sha1.cpp:111
Uint32 H2
Definition: sha1.hpp:34
sha1_hash(const std::string &str)
Make a hash from a string.
Definition: sha1.cpp:50
static void block(LexState *ls)
Definition: lparser.cpp:1081
size_t i
Definition: function.cpp:1057
GLdouble s
Definition: glew.h:1358
GLsizei const GLcharARB ** string
Definition: glew.h:4503