ATLAS Offline Software
picosha2.h
Go to the documentation of this file.
1 /*
2  The MIT License (MIT)
3 
4  Copyright (C) 2017 okdshin
5 
6  Permission is hereby granted, free of charge, to any person obtaining a copy
7  of this software and associated documentation files (the "Software"), to deal
8  in the Software without restriction, including without limitation the rights
9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  THE SOFTWARE.
23  */
24 #ifndef PICOSHA2_H
25 #define PICOSHA2_H
26 // picosha2:20140213
27 
28 #ifndef PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR
29 #define PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR \
30  1048576 //=1024*1024: default is 1MB memory
31 #endif
32 
33 #include <algorithm>
34 #include <cassert>
35 #include <iterator>
36 #include <sstream>
37 #include <vector>
38 #include <fstream>
39 namespace picosha2 {
40  typedef unsigned long word_t;
41  typedef unsigned char byte_t;
42 
43  static const size_t k_digest_size = 32;
44 
45  namespace detail {
46  inline byte_t mask_8bit(byte_t x) {return x & 0xff;}
47 
48  inline word_t mask_32bit(word_t x) {return x & 0xffffffff;}
49 
50  const word_t add_constant[64] = {
51  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
52  0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
53  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
54  0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
55  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
56  0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
57  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
58  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
59  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
60  0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
61  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
62  };
63 
65  0x6a09e667, 0xbb67ae85, 0x3c6ef372,
66  0xa54ff53a, 0x510e527f, 0x9b05688c,
67  0x1f83d9ab, 0x5be0cd19
68  };
69 
70  inline word_t ch(word_t x, word_t y, word_t z) {return (x & y) ^ ((~x) & z);}
71 
72  inline word_t maj(word_t x, word_t y, word_t z) {
73  return (x & y) ^ (x & z) ^ (y & z);
74  }
75 
76  inline word_t rotr(word_t x, std::size_t n) {
77  assert(n < 32);
78  return mask_32bit((x >> n) | (x << (32 - n)));
79  }
80 
81  inline word_t bsig0(word_t x) {return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);}
82 
83  inline word_t bsig1(word_t x) {return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);}
84 
85  inline word_t shr(word_t x, std::size_t n) {
86  assert(n < 32);
87  return x >> n;
88  }
89 
90  inline word_t ssig0(word_t x) {return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3);}
91 
92  inline word_t ssig1(word_t x) {return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10);}
93 
94  template <typename RaIter1, typename RaIter2>
95  void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last) {
96  assert(first + 64 == last);
97  static_cast<void>(last); // for avoiding unused-variable warning
98  word_t w[64];
99  std::fill(w, w + 64, 0);
100  for (std::size_t i = 0; i < 16; ++i) {
101  w[i] = (static_cast<word_t>(mask_8bit(*(first + i * 4))) << 24) |
102  (static_cast<word_t>(mask_8bit(*(first + i * 4 + 1))) << 16) |
103  (static_cast<word_t>(mask_8bit(*(first + i * 4 + 2))) << 8) |
104  (static_cast<word_t>(mask_8bit(*(first + i * 4 + 3))));
105  }
106  for (std::size_t i = 16; i < 64; ++i) {
107  w[i] = mask_32bit(ssig1(w[i - 2]) + w[i - 7] + ssig0(w[i - 15]) +
108  w[i - 16]);
109  }
110 
111  word_t a = *message_digest;
112  word_t b = *(message_digest + 1);
113  word_t c = *(message_digest + 2);
114  word_t d = *(message_digest + 3);
115  word_t e = *(message_digest + 4);
116  word_t f = *(message_digest + 5);
117  word_t g = *(message_digest + 6);
118  word_t h = *(message_digest + 7);
119 
120  for (std::size_t i = 0; i < 64; ++i) {
121  word_t temp1 = h + bsig1(e) + ch(e, f, g) + add_constant[i] + w[i];
122  word_t temp2 = bsig0(a) + maj(a, b, c);
123  h = g;
124  g = f;
125  f = e;
126  e = mask_32bit(d + temp1);
127  d = c;
128  c = b;
129  b = a;
130  a = mask_32bit(temp1 + temp2);
131  }
132  *message_digest += a;
133  *(message_digest + 1) += b;
134  *(message_digest + 2) += c;
135  *(message_digest + 3) += d;
136  *(message_digest + 4) += e;
137  *(message_digest + 5) += f;
138  *(message_digest + 6) += g;
139  *(message_digest + 7) += h;
140  for (std::size_t i = 0; i < 8; ++i) {
141  *(message_digest + i) = mask_32bit(*(message_digest + i));
142  }
143  }
144  } // namespace detail
145 
146  template <typename InIter>
147  void output_hex(InIter first, InIter last, std::ostream& os) {
148  os.setf(std::ios::hex, std::ios::basefield);
149  while (first != last) {
150  os.width(2);
151  os.fill('0');
152  os << static_cast<unsigned int>(*first);
153  ++first;
154  }
155  os.setf(std::ios::dec, std::ios::basefield);
156  }
157 
158  template <typename InIter>
159  void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str) {
160  std::ostringstream oss;
161  output_hex(first, last, oss);
162  hex_str.assign(oss.str());
163  }
164 
165  template <typename InContainer>
166  void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str) {
167  bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
168  }
169 
170  template <typename InIter>
171  std::string bytes_to_hex_string(InIter first, InIter last) {
172  std::string hex_str;
173  bytes_to_hex_string(first, last, hex_str);
174  return hex_str;
175  }
176 
177  template <typename InContainer>
178  std::string bytes_to_hex_string(const InContainer& bytes) {
179  std::string hex_str;
180  bytes_to_hex_string(bytes, hex_str);
181  return hex_str;
182  }
183 
185  public:
187 
188  void init() {
189  m_buffer_.clear();
193  }
194 
195  template <typename RaIter>
196  void process(RaIter first, RaIter last) {
197  add_to_data_length(static_cast<word_t>(std::distance(first, last)));
198  std::copy(first, last, std::back_inserter(m_buffer_));
199  std::size_t i = 0;
200  for (; i + 64 <= m_buffer_.size(); i += 64) {
202  m_buffer_.begin() + i + 64);
203  }
204  m_buffer_.erase(m_buffer_.begin(), m_buffer_.begin() + i);
205  }
206 
207  void finish() {
208  byte_t temp[64];
209 
210  std::fill(temp, temp + 64, 0);
211  std::size_t remains = m_buffer_.size();
212  std::copy(m_buffer_.begin(), m_buffer_.end(), temp);
213  temp[remains] = 0x80;
214 
215  if (remains > 55) {
216  std::fill(temp + remains + 1, temp + 64, 0);
217  detail::hash256_block(m_h_, temp, temp + 64);
218  std::fill(temp, temp + 64 - 4, 0);
219  } else {
220  std::fill(temp + remains + 1, temp + 64 - 4, 0);
221  }
222 
223  write_data_bit_length(&(temp[56]));
224  detail::hash256_block(m_h_, temp, temp + 64);
225  }
226 
227  template <typename OutIter>
228  void get_hash_bytes(OutIter first, OutIter last) const {
229  for (const word_t* iter = m_h_; iter != m_h_ + 8; ++iter) {
230  for (std::size_t i = 0; i < 4 && first != last; ++i) {
231  *(first++) = detail::mask_8bit(
232  static_cast<byte_t>((*iter >> (24 - 8 * i))));
233  }
234  }
235  }
236 
237  private:
239  word_t carry = 0;
240 
241  m_data_length_digits_[0] += n;
242  for (std::size_t i = 0; i < 4; ++i) {
243  m_data_length_digits_[i] += carry;
244  if (m_data_length_digits_[i] >= 65536u) {
245  carry = m_data_length_digits_[i] >> 16;
246  m_data_length_digits_[i] &= 65535u;
247  } else {
248  break;
249  }
250  }
251  }
252 
254  word_t data_bit_length_digits[4];
255 
257  data_bit_length_digits);
258 
259  // convert byte length to bit length (multiply 8 or shift 3 times left)
260  word_t carry = 0;
261  for (std::size_t i = 0; i < 4; ++i) {
262  word_t before_val = data_bit_length_digits[i];
263  data_bit_length_digits[i] <<= 3;
264  data_bit_length_digits[i] |= carry;
265  data_bit_length_digits[i] &= 65535u;
266  carry = (before_val >> (16 - 3)) & 65535u;
267  }
268 
269  // write data_bit_length
270  for (int i = 3; i >= 0; --i) {
271  (*begin++) = static_cast<byte_t>(data_bit_length_digits[i] >> 8);
272  (*begin++) = static_cast<byte_t>(data_bit_length_digits[i]);
273  }
274  }
275 
276  std::vector<byte_t> m_buffer_;
277  word_t m_data_length_digits_[4]; // as 64bit integer (16bit x 4 integer)
279  };
280 
281  inline void get_hash_hex_string(const hash256_one_by_one& hasher,
282  std::string& hex_str) {
283  byte_t hash[k_digest_size];
284 
285  hasher.get_hash_bytes(hash, hash + k_digest_size);
286  return bytes_to_hex_string(hash, hash + k_digest_size, hex_str);
287  }
288 
289  inline std::string get_hash_hex_string(const hash256_one_by_one& hasher) {
290  std::string hex_str;
291  get_hash_hex_string(hasher, hex_str);
292  return hex_str;
293  }
294 
295  namespace impl {
296  template <typename RaIter, typename OutIter>
297  void hash256_impl(RaIter first, RaIter last, OutIter first2, OutIter last2, int,
298  std::random_access_iterator_tag) {
299  hash256_one_by_one hasher;
300 
301  // hasher.init();
302  hasher.process(first, last);
303  hasher.finish();
304  hasher.get_hash_bytes(first2, last2);
305  }
306 
307  template <typename InputIter, typename OutIter>
308  void hash256_impl(InputIter first, InputIter last, OutIter first2,
309  OutIter last2, int buffer_size, std::input_iterator_tag) {
310  std::vector<byte_t> buffer(buffer_size);
311  hash256_one_by_one hasher;
312  // hasher.init();
313  while (first != last) {
314  int size = buffer_size;
315  for (int i = 0; i != buffer_size; ++i, ++first) {
316  if (first == last) {
317  size = i;
318  break;
319  }
320  buffer[i] = *first;
321  }
322  hasher.process(buffer.begin(), buffer.begin() + size);
323  }
324  hasher.finish();
325  hasher.get_hash_bytes(first2, last2);
326  }
327  }
328 
329  template <typename InIter, typename OutIter>
330  void hash256(InIter first, InIter last, OutIter first2, OutIter last2,
331  int buffer_size = PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR) {
333  first, last, first2, last2, buffer_size,
334  typename std::iterator_traits<InIter>::iterator_category());
335  }
336 
337  template <typename InIter, typename OutContainer>
338  void hash256(InIter first, InIter last, OutContainer& dst) {
339  hash256(first, last, dst.begin(), dst.end());
340  }
341 
342  template <typename InContainer, typename OutIter>
343  void hash256(const InContainer& src, OutIter first, OutIter last) {
344  hash256(src.begin(), src.end(), first, last);
345  }
346 
347  template <typename InContainer, typename OutContainer>
348  void hash256(const InContainer& src, OutContainer& dst) {
349  hash256(src.begin(), src.end(), dst.begin(), dst.end());
350  }
351 
352  template <typename InIter>
353  void hash256_hex_string(InIter first, InIter last, std::string& hex_str) {
354  byte_t hashed[k_digest_size];
355 
356  hash256(first, last, hashed, hashed + k_digest_size);
357  std::ostringstream oss;
358  output_hex(hashed, hashed + k_digest_size, oss);
359  hex_str.assign(oss.str());
360  }
361 
362  template <typename InIter>
363  std::string hash256_hex_string(InIter first, InIter last) {
364  std::string hex_str;
365  hash256_hex_string(first, last, hex_str);
366  return hex_str;
367  }
368 
369  inline void hash256_hex_string(const std::string& src, std::string& hex_str) {
370  hash256_hex_string(src.begin(), src.end(), hex_str);
371  }
372 
373  template <typename InContainer>
374  void hash256_hex_string(const InContainer& src, std::string& hex_str) {
375  hash256_hex_string(src.begin(), src.end(), hex_str);
376  }
377 
378  template <typename InContainer>
379  std::string hash256_hex_string(const InContainer& src) {
380  return hash256_hex_string(src.begin(), src.end());
381  }
382 
383  template<typename OutIter>void hash256(std::ifstream& f, OutIter first, OutIter last) {
384  hash256(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>(), first, last);
385  }
386 }// namespace picosha2
387 #endif // PICOSHA2_H
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
picosha2::get_hash_hex_string
void get_hash_hex_string(const hash256_one_by_one &hasher, std::string &hex_str)
Definition: picosha2.h:281
picosha2::hash256_one_by_one::m_data_length_digits_
word_t m_data_length_digits_[4]
Definition: picosha2.h:277
picosha2::hash256_one_by_one::m_h_
word_t m_h_[8]
Definition: picosha2.h:278
picosha2::byte_t
unsigned char byte_t
Definition: picosha2.h:41
WriteCellNoiseToCool.src
src
Definition: WriteCellNoiseToCool.py:513
picosha2::detail::bsig1
word_t bsig1(word_t x)
Definition: picosha2.h:83
picosha2::impl::hash256_impl
void hash256_impl(RaIter first, RaIter last, OutIter first2, OutIter last2, int, std::random_access_iterator_tag)
Definition: picosha2.h:297
picosha2::detail::maj
word_t maj(word_t x, word_t y, word_t z)
Definition: picosha2.h:72
hist_file_dump.d
d
Definition: hist_file_dump.py:137
picosha2::hash256
void hash256(InIter first, InIter last, OutIter first2, OutIter last2, int buffer_size=PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR)
Definition: picosha2.h:330
picosha2::hash256_hex_string
void hash256_hex_string(InIter first, InIter last, std::string &hex_str)
Definition: picosha2.h:353
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
picosha2::hash256_one_by_one::finish
void finish()
Definition: picosha2.h:207
picosha2::detail::shr
word_t shr(word_t x, std::size_t n)
Definition: picosha2.h:85
detail
Definition: extract_histogram_tag.cxx:14
picosha2::hash256_one_by_one::hash256_one_by_one
hash256_one_by_one()
Definition: picosha2.h:186
picosha2::detail::initial_message_digest
const word_t initial_message_digest[8]
Definition: picosha2.h:64
x
#define x
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
picosha2::hash256_one_by_one::add_to_data_length
void add_to_data_length(word_t n)
Definition: picosha2.h:238
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
picosha2::detail::bsig0
word_t bsig0(word_t x)
Definition: picosha2.h:81
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:12
picosha2::hash256_one_by_one::get_hash_bytes
void get_hash_bytes(OutIter first, OutIter last) const
Definition: picosha2.h:228
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
beamspotman.n
n
Definition: beamspotman.py:731
picosha2::detail::mask_32bit
word_t mask_32bit(word_t x)
Definition: picosha2.h:48
hist_file_dump.f
f
Definition: hist_file_dump.py:135
picosha2::detail::hash256_block
void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last)
Definition: picosha2.h:95
picosha2::word_t
unsigned long word_t
Definition: picosha2.h:40
picosha2::bytes_to_hex_string
void bytes_to_hex_string(InIter first, InIter last, std::string &hex_str)
Definition: picosha2.h:159
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
picosha2::hash256_one_by_one::process
void process(RaIter first, RaIter last)
Definition: picosha2.h:196
fill
void fill(H5::Group &out_file, size_t iterations)
Definition: test-hdf5-writer.cxx:95
picosha2::hash256_one_by_one
Definition: picosha2.h:184
picosha2::hash256_one_by_one::write_data_bit_length
void write_data_bit_length(byte_t *begin)
Definition: picosha2.h:253
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
picosha2::detail::ch
word_t ch(word_t x, word_t y, word_t z)
Definition: picosha2.h:70
picosha2::detail::ssig0
word_t ssig0(word_t x)
Definition: picosha2.h:90
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
a
TList * a
Definition: liststreamerinfos.cxx:10
y
#define y
h
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
picosha2::hash256_one_by_one::m_buffer_
std::vector< byte_t > m_buffer_
Definition: picosha2.h:276
DeMoScan.first
bool first
Definition: DeMoScan.py:536
picosha2::detail::mask_8bit
byte_t mask_8bit(byte_t x)
Definition: picosha2.h:46
PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR
#define PICOSHA2_BUFFER_SIZE_FOR_INPUT_ITERATOR
Definition: picosha2.h:29
calibdata.copy
bool copy
Definition: calibdata.py:27
picosha2::detail::add_constant
const word_t add_constant[64]
Definition: picosha2.h:50
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
picosha2
Definition: picosha2.h:39
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
python.compressB64.c
def c
Definition: compressB64.py:93
picosha2::output_hex
void output_hex(InIter first, InIter last, std::ostream &os)
Definition: picosha2.h:147
picosha2::detail::ssig1
word_t ssig1(word_t x)
Definition: picosha2.h:92
picosha2::detail::rotr
word_t rotr(word_t x, std::size_t n)
Definition: picosha2.h:76
picosha2::hash256_one_by_one::init
void init()
Definition: picosha2.h:188