A toolkit for working with phylogenetic data.
v0.19.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sha256.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_TOOLS_SHA256_H_
2 #define GENESIS_UTILS_TOOLS_SHA256_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include <array>
35 #include <cstdint>
36 #include <iosfwd>
37 #include <string>
38 
39 namespace genesis {
40 namespace utils {
41 
42 // ================================================================================================
43 // SHA256
44 // ================================================================================================
45 
96 class SHA256
97 {
98 public:
99 
100  // -------------------------------------------------------------------------
101  // Typedefs and Constants
102  // -------------------------------------------------------------------------
103 
104  static const size_t BlockSize = ( 512 / 8 );
105  static const size_t DigestSize = ( 256 / 8);
106 
114  using DigestType = std::array< uint32_t, 8 >;
115 
116  // -------------------------------------------------------------------------
117  // Constructors and Rule of Five
118  // -------------------------------------------------------------------------
119 
120  SHA256();
121  ~SHA256() = default;
122 
123  SHA256( SHA256 const& ) = default;
124  SHA256( SHA256&& ) = default;
125 
126  SHA256& operator= ( SHA256 const& ) = default;
127  SHA256& operator= ( SHA256&& ) = default;
128 
129  // -------------------------------------------------------------------------
130  // Member Functions
131  // -------------------------------------------------------------------------
132 
133  void update( std::string const& s );
134  void update( std::istream& is );
135  void update( char const* input, size_t length );
136 
137  std::string final_hex();
139 
140  static std::string from_file_hex( std::string const& filename );
141  static DigestType from_file_digest( std::string const& filename );
142 
143  static std::string from_string_hex( std::string const& input );
144  static DigestType from_string_digest( std::string const& input );
145 
146  static std::string digest_to_hex( DigestType const& digest );
147  static DigestType hex_to_digest( std::string const& hex );
148 
149  // -------------------------------------------------------------------------
150  // Internal Functions
151  // -------------------------------------------------------------------------
152 
153 private:
154 
155  void reset_();
156 
157  // SHA256 block update operation. Continues an SHA256 message-digest
158  // operation, processing another message block
159  void update_( unsigned char const* message, size_t len );
160 
161  void transform_( unsigned char const* message, unsigned int block_nb );
162 
163  static inline uint32_t SHA2_SHFR( uint32_t x, uint32_t n )
164  {
165  return x >> n;
166  }
167 
168  static inline uint32_t SHA2_ROTR( uint32_t x, uint32_t n )
169  {
170  return ((x >> n) | (x << ((sizeof(x) << 3) - n)));
171  }
172 
173  static inline uint32_t SHA2_ROTL( uint32_t x, uint32_t n )
174  {
175  return ((x << n) | (x >> ((sizeof(x) << 3) - n)));
176  }
177 
178  static inline uint32_t SHA2_CH( uint32_t x, uint32_t y, uint32_t z )
179  {
180  return ((x & y) ^ (~x & z));
181  }
182 
183  static inline uint32_t SHA2_MAJ( uint32_t x, uint32_t y, uint32_t z )
184  {
185  return ((x & y) ^ (x & z) ^ (y & z));
186  }
187 
188  static inline uint32_t SHA256_F1( uint32_t x )
189  {
190  return (SHA2_ROTR(x, 2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22));
191  }
192 
193  static inline uint32_t SHA256_F2( uint32_t x )
194  {
195  return (SHA2_ROTR(x, 6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25));
196  }
197 
198  static inline uint32_t SHA256_F3( uint32_t x )
199  {
200  return (SHA2_ROTR(x, 7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x, 3));
201  }
202 
203  static inline uint32_t SHA256_F4( uint32_t x )
204  {
205  return (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10));
206  }
207 
208  static inline uint32_t SHA2_PACK32( unsigned char const* str )
209  {
210  return ((uint32_t) *((str) + 3) )
211  | ((uint32_t) *((str) + 2) << 8)
212  | ((uint32_t) *((str) + 1) << 16)
213  | ((uint32_t) *((str) + 0) << 24)
214  ;
215  }
216 
217  static inline void SHA2_UNPACK32( uint32_t x, unsigned char* str)
218  {
219  *((str) + 3) = (uint8_t) ((x) );
220  *((str) + 2) = (uint8_t) ((x) >> 8);
221  *((str) + 1) = (uint8_t) ((x) >> 16);
222  *((str) + 0) = (uint8_t) ((x) >> 24);
223  }
224 
225  // -------------------------------------------------------------------------
226  // Data Members
227  // -------------------------------------------------------------------------
228 
229 private:
230 
231  const static uint32_t sha256_k[];
232 
233  unsigned int tot_len_;
234  unsigned int len_;
235  unsigned char block_[ 2 * BlockSize ];
236 
237  DigestType digest_;
238 
239 };
240 
241 } // namespace utils
242 } // namespace genesis
243 
244 // ================================================================================================
245 // Standard Hash Function
246 // ================================================================================================
247 
248 namespace std
249 {
256  template<>
257  struct hash<genesis::utils::SHA256::DigestType>
258  {
260  using result_type = std::size_t;
261 
263  result_type hash = 0;
264  hash ^= s[0] ^ ( static_cast<result_type>( s[1] ) << 32 );
265  hash ^= s[2] ^ ( static_cast<result_type>( s[3] ) << 32 );
266  hash ^= s[4] ^ ( static_cast<result_type>( s[5] ) << 32 );
267  hash ^= s[6] ^ ( static_cast<result_type>( s[7] ) << 32 );
268  return hash;
269  }
270  };
271 }
272 
273 #endif // include guard
std::array< uint32_t, 8 > DigestType
Store a SHA256 digest.
Definition: sha256.hpp:114
std::string final_hex()
Finish the calculation, prepare the object for next use, and return the hash.
Definition: sha256.cpp:157
Calculate SHA256 hashes for strings and files.
Definition: sha256.hpp:96
static DigestType hex_to_digest(std::string const &hex)
Definition: sha256.cpp:252
SHA256 & operator=(SHA256 const &)=default
DigestType final_digest()
Finish the calculation, prepare the object for next use, and return the digest.
Definition: sha256.cpp:166
static DigestType from_file_digest(std::string const &filename)
Calculate the hash digest for the content of a file, given its path.
Definition: sha256.cpp:205
genesis::utils::SHA256::DigestType argument_type
Definition: sha256.hpp:259
SHA256()
Initialize the object for use.
Definition: sha256.cpp:113
void update(std::string const &s)
Add the contents of a string to the hash digest.
Definition: sha256.cpp:125
static std::string digest_to_hex(DigestType const &digest)
Definition: sha256.cpp:233
static const size_t DigestSize
Definition: sha256.hpp:105
static std::string from_file_hex(std::string const &filename)
Calculate the checksum for the content of a file, given its path.
Definition: sha256.cpp:194
static DigestType from_string_digest(std::string const &input)
Calculate the hash digest for the content of a string.
Definition: sha256.cpp:226
static const size_t BlockSize
Definition: sha256.hpp:104
result_type operator()(argument_type const &s) const
Definition: sha256.hpp:262
static std::string from_string_hex(std::string const &input)
Calculate the checksum for the content of a string.
Definition: sha256.cpp:216
double length(Tree const &tree)
Get the length of the tree, i.e., the sum of all branch lengths.