A library for working with phylogenetic and population genetic data.
v0.27.0
sha256.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_TOOLS_HASH_SHA256_H_
2 #define GENESIS_UTILS_TOOLS_HASH_SHA256_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2019 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 
35 
36 #include <array>
37 #include <cstdint>
38 #include <iosfwd>
39 #include <string>
40 
41 namespace genesis {
42 namespace utils {
43 
44 // ================================================================================================
45 // SHA256
46 // ================================================================================================
47 
102 class SHA256
103 {
104 public:
105 
106  // -------------------------------------------------------------------------
107  // Typedefs and Constants
108  // -------------------------------------------------------------------------
109 
110  static const size_t BlockSize = ( 512 / 8 );
111  static const size_t DigestSize = ( 256 / 8);
112 
120  using DigestType = std::array< uint32_t, 8 >;
121 
122  // -------------------------------------------------------------------------
123  // Constructors and Rule of Five
124  // -------------------------------------------------------------------------
125 
129  SHA256();
130  ~SHA256() = default;
131 
132  SHA256( SHA256 const& ) = default;
133  SHA256( SHA256&& ) = default;
134 
135  SHA256& operator= ( SHA256 const& ) = default;
136  SHA256& operator= ( SHA256&& ) = default;
137 
138  // -------------------------------------------------------------------------
139  // Full Hashing
140  // -------------------------------------------------------------------------
141 
145  static std::string read_hex( std::shared_ptr<BaseInputSource> source );
146 
150  static DigestType read_digest( std::shared_ptr<BaseInputSource> source );
151 
152  static std::string digest_to_hex( DigestType const& digest );
153  static DigestType hex_to_digest( std::string const& hex );
154 
155  // -------------------------------------------------------------------------
156  // Iterative Hashing
157  // -------------------------------------------------------------------------
158 
162  void clear();
163 
164  void update( std::shared_ptr<BaseInputSource> source );
165  void update( std::string const& s );
166  void update( std::istream& is );
167  void update( char const* input, size_t length );
168 
172  std::string final_hex();
173 
178 
179  // -------------------------------------------------------------------------
180  // Internal Functions
181  // -------------------------------------------------------------------------
182 
183 private:
184 
185  void reset_();
186 
187  // SHA256 block update operation. Continues an SHA256 message-digest
188  // operation, processing another message block
189  void update_( unsigned char const* message, size_t len );
190 
191  void transform_( unsigned char const* message, unsigned int block_nb );
192 
193  static inline uint32_t SHA2_SHFR( uint32_t x, uint32_t n )
194  {
195  return x >> n;
196  }
197 
198  static inline uint32_t SHA2_ROTR( uint32_t x, uint32_t n )
199  {
200  return ((x >> n) | (x << ((sizeof(x) << 3) - n)));
201  }
202 
203  static inline uint32_t SHA2_ROTL( uint32_t x, uint32_t n )
204  {
205  return ((x << n) | (x >> ((sizeof(x) << 3) - n)));
206  }
207 
208  static inline uint32_t SHA2_CH( uint32_t x, uint32_t y, uint32_t z )
209  {
210  return ((x & y) ^ (~x & z));
211  }
212 
213  static inline uint32_t SHA2_MAJ( uint32_t x, uint32_t y, uint32_t z )
214  {
215  return ((x & y) ^ (x & z) ^ (y & z));
216  }
217 
218  static inline uint32_t SHA256_F1( uint32_t x )
219  {
220  return (SHA2_ROTR(x, 2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22));
221  }
222 
223  static inline uint32_t SHA256_F2( uint32_t x )
224  {
225  return (SHA2_ROTR(x, 6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25));
226  }
227 
228  static inline uint32_t SHA256_F3( uint32_t x )
229  {
230  return (SHA2_ROTR(x, 7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x, 3));
231  }
232 
233  static inline uint32_t SHA256_F4( uint32_t x )
234  {
235  return (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10));
236  }
237 
238  static inline uint32_t SHA2_PACK32( unsigned char const* str )
239  {
240  return ((uint32_t) *((str) + 3) )
241  | ((uint32_t) *((str) + 2) << 8)
242  | ((uint32_t) *((str) + 1) << 16)
243  | ((uint32_t) *((str) + 0) << 24)
244  ;
245  }
246 
247  static inline void SHA2_UNPACK32( uint32_t x, unsigned char* str)
248  {
249  *((str) + 3) = (uint8_t) ((x) );
250  *((str) + 2) = (uint8_t) ((x) >> 8);
251  *((str) + 1) = (uint8_t) ((x) >> 16);
252  *((str) + 0) = (uint8_t) ((x) >> 24);
253  }
254 
255  // -------------------------------------------------------------------------
256  // Data Members
257  // -------------------------------------------------------------------------
258 
259 private:
260 
261  const static uint32_t sha256_k[];
262 
263  unsigned int tot_len_;
264  unsigned int len_;
265  unsigned char block_[ 2 * BlockSize ];
266 
267  DigestType digest_;
268 
269 };
270 
271 } // namespace utils
272 } // namespace genesis
273 
274 // ================================================================================================
275 // Standard Hash Function
276 // ================================================================================================
277 
278 namespace std
279 {
286  template<>
287  struct hash<genesis::utils::SHA256::DigestType>
288  {
290  using result_type = std::size_t;
291 
293  result_type result = 0;
294  result ^= s[0] ^ ( static_cast<result_type>( s[1] ) << 32 );
295  result ^= s[2] ^ ( static_cast<result_type>( s[3] ) << 32 );
296  result ^= s[4] ^ ( static_cast<result_type>( s[5] ) << 32 );
297  result ^= s[6] ^ ( static_cast<result_type>( s[7] ) << 32 );
298  return result;
299  }
300  };
301 }
302 
303 #endif // include guard
genesis::utils::SHA256::DigestType
std::array< uint32_t, 8 > DigestType
Store a SHA256 digest.
Definition: sha256.hpp:120
genesis::utils::SHA256::final_hex
std::string final_hex()
Finish the calculation, prepare the object for next use, and return the hash.
Definition: sha256.cpp:260
genesis::utils::SHA256::read_digest
static DigestType read_digest(std::shared_ptr< BaseInputSource > source)
Calculate the hash digest for the content of an input source.
Definition: sha256.cpp:144
genesis::utils::SHA256::clear
void clear()
Reset to initial state, that is, delete any intermediate input from update() calls.
Definition: sha256.cpp:208
genesis::utils::SHA256::hex_to_digest
static DigestType hex_to_digest(std::string const &hex)
Definition: sha256.cpp:170
genesis::utils::SHA256::update
void update(std::shared_ptr< BaseInputSource > source)
Definition: sha256.cpp:213
genesis::tree::length
double length(Tree const &tree)
Get the length of the tree, i.e., the sum of all branch lengths.
Definition: tree/common_tree/functions.cpp:160
genesis::utils::SHA256::operator=
SHA256 & operator=(SHA256 const &)=default
genesis::utils::SHA256::final_digest
DigestType final_digest()
Finish the calculation, prepare the object for next use, and return the digest.
Definition: sha256.cpp:266
input_source.hpp
genesis::utils::SHA256::read_hex
static std::string read_hex(std::shared_ptr< BaseInputSource > source)
Calculate the checksum for the content of an input source.
Definition: sha256.cpp:137
std::hash< genesis::utils::SHA256::DigestType >::operator()
result_type operator()(argument_type const &s) const
Definition: sha256.hpp:292
genesis::utils::SHA256::SHA256
SHA256()
Initialize the object for use.
Definition: sha256.cpp:128
genesis::utils::SHA256::~SHA256
~SHA256()=default
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::SHA256::digest_to_hex
static std::string digest_to_hex(DigestType const &digest)
Definition: sha256.cpp:151
std::hash< genesis::utils::SHA256::DigestType >::argument_type
genesis::utils::SHA256::DigestType argument_type
Definition: sha256.hpp:289
genesis::utils::SHA256::BlockSize
static const size_t BlockSize
Definition: sha256.hpp:110
genesis::utils::SHA256
Calculate SHA256 hashes for strings and files.
Definition: sha256.hpp:102
genesis::utils::SHA256::DigestSize
static const size_t DigestSize
Definition: sha256.hpp:111
std::hash< genesis::utils::SHA256::DigestType >::result_type
std::size_t result_type
Definition: sha256.hpp:290