sha.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
37 #ifndef __INCLUDE_SHA__
38 #define __INCLUDE_SHA__
39 
40 #include <cstring>
41 
42 #ifndef __INCLUDE_MIST_CONF_H__
43 #include "config/mist_conf.h"
44 #endif
45 
46 #ifndef __INCLUDE_MIST_ENDIAN__
47 #include "config/endian.h"
48 #endif
49 
50 #ifndef __INCLUDE_HASH_ALGORITHM__
51 #include "hash_algorithm.h"
52 #endif
53 
54 
55 // mist名前空間の始まり
57 
58 
59 
62 
63 
65 class sha1 : public hash_algorithm
66 {
67 private:
68  typedef hash_algorithm base;
69 
70 public:
73  typedef base::uint8 uint8;
74  typedef base::uint32 uint32;
75  typedef base::uint64 uint64;
76 
77 
78 protected:
79  uint32 R( uint32 a, uint32 s ){ return( ( a << s ) | ( a >> ( 32 - s ) ) ); }
80 
81  void ToCurrentEndian( uint32 *x, size_type len )
82  {
83  for( size_type i = 0 ; i < len ; i++ )
84  {
85  x[ i ] = to_current_endian( byte_array< uint32 >( x[ i ] ), false ).get_value( );
86  }
87  }
88 
89  void FromCurrentEndian( uint32 *x, size_type len )
90  {
91  for( size_type i = 0 ; i < len ; i++ )
92  {
93  x[ i ] = from_current_endian( byte_array< uint32 >( x[ i ] ), false ).get_value( );
94  }
95  }
96 
97  void Round( uint32 &a, uint32 &b, uint32 &c, uint32 &d, uint32 &e, uint32 x[ 16 ] )
98  {
99  size_type i;
100  uint32 W[ 80 ];
101 
102  memcpy( W, x, sizeof( uint32 ) * 16 );
103 
104  for( i = 16 ; i < 80 ; i++ )
105  {
106  W[ i ] = R( W[ i - 3 ] ^ W[ i - 8 ] ^ W[ i - 14 ] ^ W[ i- 16 ], 1 );
107  }
108 
109  uint32 A = a;
110  uint32 B = b;
111  uint32 C = c;
112  uint32 D = d;
113  uint32 E = e;
114 
115  // ワードブロックごとの処理を行う
116  for( i = 0 ; i < 20 ; i++ )
117  {
118  uint32 temp = R( A, 5 ) + ( ( B & C ) | ( ~B & D ) ) + E + W[ i ] + 0x5a827999;
119  E = D;
120  D = C;
121  C = R( B, 30 );
122  B = A;
123  A = temp;
124  }
125 
126  for( ; i < 40 ; i++ )
127  {
128  uint32 temp = R( A, 5 ) + ( B ^ C ^ D ) + E + W[ i ] + 0x6ed9eba1;
129  E = D;
130  D = C;
131  C = R( B, 30 );
132  B = A;
133  A = temp;
134  }
135 
136  for( ; i < 60 ; i++ )
137  {
138  uint32 temp = R( A, 5 ) + ( ( B & C ) | ( B & D ) | ( C & D ) ) + E + W[ i ] + 0x8f1bbcdc;
139  E = D;
140  D = C;
141  C = R( B, 30 );
142  B = A;
143  A = temp;
144  }
145 
146  for( ; i < 80 ; i++ )
147  {
148  uint32 temp = R( A, 5 ) + ( B ^ C ^ D ) + E + W[ i ] + 0xca62c1d6;
149  E = D;
150  D = C;
151  C = R( B, 30 );
152  B = A;
153  A = temp;
154  }
155 
156  a += A;
157  b += B;
158  c += C;
159  d += D;
160  e += E;
161  }
162 
163 public:
165  virtual void compute_hash( const void *bytes, uint64 length )
166  {
167  size_type len = static_cast< size_type >( length );
168  length *= 8;
169 
170  // 出力用のダイジェストバイト列を 32 ビット単位で処理できるようにする
171  uint32 &A = *reinterpret_cast< uint32 * >( digest );
172  uint32 &B = *reinterpret_cast< uint32 * >( digest + 4 );
173  uint32 &C = *reinterpret_cast< uint32 * >( digest + 8 );
174  uint32 &D = *reinterpret_cast< uint32 * >( digest + 12 );
175  uint32 &E = *reinterpret_cast< uint32 * >( digest + 16 );
176 
177  // ダイジェストバイト列の初期化
178  const uint32 H0 = 0x67452301;
179  const uint32 H1 = 0xefcdab89;
180  const uint32 H2 = 0x98badcfe;
181  const uint32 H3 = 0x10325476;
182  const uint32 H4 = 0xc3d2e1f0;
183 
184  A = H0;
185  B = H1;
186  C = H2;
187  D = H3;
188  E = H4;
189 
190  size_type i;
191  uint32 x[ 16 ];
192  uint8 *xx = reinterpret_cast< uint8 * >( x );
193  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
194 
195  // 入力データに対してメッセージ処理を行う
196  for( i = 0 ; i + 64 < len ; i += 64 )
197  {
198  memcpy( xx, data + i, sizeof( uint8 ) * 64 );
199  ToCurrentEndian( x, 16 );
200  Round( A, B, C, D, E, x );
201  }
202 
203  size_type rest = len - i;
204 
205  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
206  if( rest >= 64 - 8 )
207  {
208  memcpy( xx, data + i, sizeof( uint8 ) * rest );
209  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
210  // 先頭のビットを 1 にする
211  xx[ rest ] = 0x80;
212 
213  // メッセージ処理を行う
214  ToCurrentEndian( x, 16 );
215  Round( A, B, C, D, E, x );
216 
217  // バイト長の分の処理を行う
218  memset( xx, 0, sizeof( uint8 ) * 64 );
219  x[ 14 ] = static_cast< uint32 >( length >> 32 );
220  x[ 15 ] = static_cast< uint32 >( length );
221 
222  // メッセージ処理を行う
223  Round( A, B, C, D, E, x );
224  }
225  else
226  {
227  memcpy( xx, data + i, sizeof( uint8 ) * rest );
228  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
229  // 先頭のビットを 1 にする
230  xx[ rest ] = 0x80;
231 
232  ToCurrentEndian( x, 16 );
233 
234  // バイト長の分の値を付加する
235  x[ 14 ] = static_cast< uint32 >( length >> 32 );
236  x[ 15 ] = static_cast< uint32 >( length );
237 
238  // メッセージ処理を行う
239  Round( A, B, C, D, E, x );
240  }
241 
242  FromCurrentEndian( reinterpret_cast< uint32 * >( digest ), 5 );
243  }
244 
245 
247  virtual const std::string name( ) const{ return( "SHA1" ); }
248 
249 
251  sha1( ) : base( "da39a3ee5e6b4b0d3255bfef95601890afd80709" ){ }
252 
254  sha1( const std::string &str ) : base( 20 ) { base::compute_hash( str ); }
255 
257  sha1( const void *data, uint64 len ) : base( 20 ){ compute_hash( data, len ); }
258 
259 };
260 
261 
262 
264 class sha256 : public hash_algorithm
265 {
266 private:
267  typedef hash_algorithm base;
268 
269 public:
272  typedef base::uint8 uint8;
275 
276 
277 protected:
278  uint32 S( uint32 a, uint32 s ){ return( ( a >> s ) | ( a << ( 32 - s ) ) ); }
279  uint32 R( uint32 a, uint32 s ){ return( a >> s ); }
280  uint32 Ch( uint32 x, uint32 y, uint32 z ){ return( ( x & y ) ^ ( ~x & z ) ); }
281  uint32 Maj( uint32 x, uint32 y, uint32 z ){ return( ( x & y ) ^ ( x & z ) ^ ( y & z ) ); }
282  uint32 S0( uint32 x ){ return( S( x, 2 ) ^ S( x, 13 ) ^ S( x, 22 ) ); }
283  uint32 S1( uint32 x ){ return( S( x, 6 ) ^ S( x, 11 ) ^ S( x, 25 ) ); }
284  uint32 s0( uint32 x ){ return( S( x, 7 ) ^ S( x, 18 ) ^ R( x, 3 ) ); }
285  uint32 s1( uint32 x ){ return( S( x, 17 ) ^ S( x, 19 ) ^ R( x, 10 ) ); }
286 
287  void ToCurrentEndian( uint32 *x, size_type len )
288  {
289  for( size_type i = 0 ; i < len ; i++ )
290  {
291  x[ i ] = to_current_endian( byte_array< uint32 >( x[ i ] ), false ).get_value( );
292  }
293  }
294 
295  void FromCurrentEndian( uint32 *x, size_type len )
296  {
297  for( size_type i = 0 ; i < len ; i++ )
298  {
299  x[ i ] = from_current_endian( byte_array< uint32 >( x[ i ] ), false ).get_value( );
300  }
301  }
302 
303  void Round( uint32 *H, uint32 x[ 16 ] )
304  {
305  size_type i;
306  uint32 W[ 64 ];
307 
308  memcpy( W, x, sizeof( uint32 ) * 16 );
309 
310  for( i = 16 ; i < 64 ; i++ )
311  {
312  W[ i ] = s1( W[ i - 2 ] ) + W[ i - 7 ] + s0( W[ i - 15 ] ) + W[ i- 16 ];
313  }
314 
315  uint32 a = H[ 0 ];
316  uint32 b = H[ 1 ];
317  uint32 c = H[ 2 ];
318  uint32 d = H[ 3 ];
319  uint32 e = H[ 4 ];
320  uint32 f = H[ 5 ];
321  uint32 g = H[ 6 ];
322  uint32 h = H[ 7 ];
323 
324  static uint32 K[] =
325  {
326  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
327  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
328  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
329  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
330  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
331  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
332  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
333  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
334  };
335 
336  // ワードブロックごとの処理を行う
337  for( i = 0 ; i < 64 ; i++ )
338  {
339  uint32 T1 = h + S1( e ) + Ch( e, f, g ) + K[ i ] + W[ i ];
340  uint32 T2 = S0( a ) + Maj( a, b, c );
341  h = g;
342  g = f;
343  f = e;
344  e = d + T1;
345  d = c;
346  c = b;
347  b = a;
348  a = T1 + T2;
349  }
350 
351  H[ 0 ] += a;
352  H[ 1 ] += b;
353  H[ 2 ] += c;
354  H[ 3 ] += d;
355  H[ 4 ] += e;
356  H[ 5 ] += f;
357  H[ 6 ] += g;
358  H[ 7 ] += h;
359  }
360 
361 public:
363  virtual void compute_hash( const void *bytes, uint64 length )
364  {
365  size_type len = static_cast< size_type >( length );
366  length *= 8;
367 
368  // 出力用のダイジェストバイト列を 32 ビット単位で処理できるようにする
369  uint32 *H = reinterpret_cast< uint32 * >( digest );
370 
371  // ダイジェストバイト列の初期化
372  H[ 0 ] = 0x6a09e667;
373  H[ 1 ] = 0xbb67ae85;
374  H[ 2 ] = 0x3c6ef372;
375  H[ 3 ] = 0xa54ff53a;
376  H[ 4 ] = 0x510e527f;
377  H[ 5 ] = 0x9b05688c;
378  H[ 6 ] = 0x1f83d9ab;
379  H[ 7 ] = 0x5be0cd19;
380 
381  size_type i;
382  uint32 x[ 16 ];
383  uint8 *xx = reinterpret_cast< uint8 * >( x );
384  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
385 
386  // 入力データに対してメッセージ処理を行う
387  for( i = 0 ; i + 64 < len ; i += 64 )
388  {
389  memcpy( xx, data + i, sizeof( uint8 ) * 64 );
390  ToCurrentEndian( x, 16 );
391  Round( H, x );
392  }
393 
394  size_type rest = len - i;
395 
396  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
397  if( rest >= 64 - 8 )
398  {
399  memcpy( xx, data + i, sizeof( uint8 ) * rest );
400  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
401  // 先頭のビットを 1 にする
402  xx[ rest ] = 0x80;
403 
404  // メッセージ処理を行う
405  ToCurrentEndian( x, 16 );
406  Round( H, x );
407 
408  // バイト長の分の処理を行う
409  memset( xx, 0, sizeof( uint8 ) * 64 );
410  x[ 14 ] = static_cast< uint32 >( length >> 32 );
411  x[ 15 ] = static_cast< uint32 >( length );
412 
413  // メッセージ処理を行う
414  Round( H, x );
415  }
416  else
417  {
418  memcpy( xx, data + i, sizeof( uint8 ) * rest );
419  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
420  // 先頭のビットを 1 にする
421  xx[ rest ] = 0x80;
422 
423  ToCurrentEndian( x, 16 );
424 
425  // バイト長の分の値を付加する
426  x[ 14 ] = static_cast< uint32 >( length >> 32 );
427  x[ 15 ] = static_cast< uint32 >( length );
428 
429  // メッセージ処理を行う
430  Round( H, x );
431  }
432 
433  FromCurrentEndian( reinterpret_cast< uint32 * >( digest ), 8 );
434  }
435 
436 
438  virtual const std::string name( ) const{ return( "SHA-256" ); }
439 
440 
442  sha256( ) : base( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" ){ }
443 
445  sha256( const std::string &str ) : base( 32 ) { base::compute_hash( str ); }
446 
448  sha256( const void *data, uint64 len ) : base( 32 ){ compute_hash( data, len ); }
449 
450 };
451 
452 
453 
455 class sha384 : public hash_algorithm
456 {
457 private:
458  typedef hash_algorithm base;
459 
460 public:
463  typedef base::uint8 uint8;
466 
467 
468 protected:
469  uint64 S( const uint64 &a, uint32 s ){ return( ( a >> s ) | ( a << ( 64 - s ) ) ); }
470  uint64 R( const uint64 &a, uint32 s ){ return( a >> s ); }
471  uint64 Ch( const uint64 &x, const uint64 &y, const uint64 &z ){ return( ( x & y ) ^ ( ~x & z ) ); }
472  uint64 Maj( const uint64 &x, const uint64 &y, const uint64 &z ){ return( ( x & y ) ^ ( x & z ) ^ ( y & z ) ); }
473  uint64 S0( const uint64 &x ){ return( S( x, 28 ) ^ S( x, 34 ) ^ S( x, 39 ) ); }
474  uint64 S1( const uint64 &x ){ return( S( x, 14 ) ^ S( x, 18 ) ^ S( x, 41 ) ); }
475  uint64 s0( const uint64 &x ){ return( S( x, 1 ) ^ S( x, 8 ) ^ R( x, 7 ) ); }
476  uint64 s1( const uint64 &x ){ return( S( x, 19 ) ^ S( x, 61 ) ^ R( x, 6 ) ); }
477 
478  void ToCurrentEndian( uint64 *x, size_type len )
479  {
480  for( size_type i = 0 ; i < len ; i++ )
481  {
482  x[ i ] = to_current_endian( byte_array< uint64 >( x[ i ] ), false ).get_value( );
483  }
484  }
485 
486  void FromCurrentEndian( uint64 *x, size_type len )
487  {
488  for( size_type i = 0 ; i < len ; i++ )
489  {
490  x[ i ] = from_current_endian( byte_array< uint64 >( x[ i ] ), false ).get_value( );
491  }
492  }
493 
494  void Round( uint64 *H, uint64 x[ 16 ] )
495  {
496  size_type i;
497  uint64 W[ 80 ];
498 
499  memcpy( W, x, sizeof( uint64 ) * 16 );
500 
501  for( i = 16 ; i < 80 ; i++ )
502  {
503  W[ i ] = s1( W[ i - 2 ] ) + W[ i - 7 ] + s0( W[ i - 15 ] ) + W[ i- 16 ];
504  }
505 
506  uint64 a = H[ 0 ];
507  uint64 b = H[ 1 ];
508  uint64 c = H[ 2 ];
509  uint64 d = H[ 3 ];
510  uint64 e = H[ 4 ];
511  uint64 f = H[ 5 ];
512  uint64 g = H[ 6 ];
513  uint64 h = H[ 7 ];
514 
515 
516  static uint64 K[] = { 4794697086780616226ULL, 8158064640168781261ULL, 13096744586834688815ULL, 16840607885511220156ULL,
517  4131703408338449720ULL, 6480981068601479193ULL, 10538285296894168987ULL, 12329834152419229976ULL,
518  15566598209576043074ULL, 1334009975649890238ULL, 2608012711638119052ULL, 6128411473006802146ULL,
519  8268148722764581231ULL, 9286055187155687089ULL, 11230858885718282805ULL, 13951009754708518548ULL,
520  16472876342353939154ULL, 17275323862435702243ULL, 1135362057144423861ULL, 2597628984639134821ULL,
521  3308224258029322869ULL, 5365058923640841347ULL, 6679025012923562964ULL, 8573033837759648693ULL,
522  10970295158949994411ULL, 12119686244451234320ULL, 12683024718118986047ULL, 13788192230050041572ULL,
523  14330467153632333762ULL, 15395433587784984357ULL, 489312712824947311ULL, 1452737877330783856ULL,
524  2861767655752347644ULL, 3322285676063803686ULL, 5560940570517711597ULL, 5996557281743188959ULL,
525  7280758554555802590ULL, 8532644243296465576ULL, 9350256976987008742ULL, 10552545826968843579ULL,
526  11727347734174303076ULL, 12113106623233404929ULL, 14000437183269869457ULL, 14369950271660146224ULL,
527  15101387698204529176ULL, 15463397548674623760ULL, 17586052441742319658ULL, 1182934255886127544ULL,
528  1847814050463011016ULL, 2177327727835720531ULL, 2830643537854262169ULL, 3796741975233480872ULL,
529  4115178125766777443ULL, 5681478168544905931ULL, 6601373596472566643ULL, 7507060721942968483ULL,
530  8399075790359081724ULL, 8693463985226723168ULL, 9568029438360202098ULL, 10144078919501101548ULL,
531  10430055236837252648ULL, 11840083180663258601ULL, 13761210420658862357ULL, 14299343276471374635ULL,
532  14566680578165727644ULL, 15097957966210449927ULL, 16922976911328602910ULL, 17689382322260857208ULL,
533  500013540394364858ULL, 748580250866718886ULL, 1242879168328830382ULL, 1977374033974150939ULL,
534  2944078676154940804ULL, 3659926193048069267ULL, 4368137639120453308ULL, 4836135668995329356ULL,
535  5532061633213252278ULL, 6448918945643986474ULL, 6902733635092675308ULL, 7801388544844847127ULL };
536 
537 
538  // ワードブロックごとの処理を行う
539  for( i = 0 ; i < 80 ; i++ )
540  {
541  uint64 T1 = h + S1( e ) + Ch( e, f, g ) + K[ i ] + W[ i ];
542  uint64 T2 = S0( a ) + Maj( a, b, c );
543  h = g;
544  g = f;
545  f = e;
546  e = d + T1;
547  d = c;
548  c = b;
549  b = a;
550  a = T1 + T2;
551  }
552 
553  H[ 0 ] += a;
554  H[ 1 ] += b;
555  H[ 2 ] += c;
556  H[ 3 ] += d;
557  H[ 4 ] += e;
558  H[ 5 ] += f;
559  H[ 6 ] += g;
560  H[ 7 ] += h;
561  }
562 
563 public:
565  virtual void compute_hash( const void *bytes, uint64 length )
566  {
567  size_type len = static_cast< size_type >( length );
568  length *= 8;
569 
570  // 出力用のダイジェストバイト列
571  uint64 H[ 8 ];
572 
573  // ダイジェストバイト列の初期化
574  H[ 0 ] = 14680500436340154072ULL;
575  H[ 1 ] = 7105036623409894663ULL;
576  H[ 2 ] = 10473403895298186519ULL;
577  H[ 3 ] = 1526699215303891257ULL;
578  H[ 4 ] = 7436329637833083697ULL;
579  H[ 5 ] = 10282925794625328401ULL;
580  H[ 6 ] = 15784041429090275239ULL;
581  H[ 7 ] = 5167115440072839076ULL;
582 
583  size_type i;
584  uint64 x[ 16 ];
585  uint8 *xx = reinterpret_cast< uint8 * >( x );
586  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
587 
588  // 入力データに対してメッセージ処理を行う
589  for( i = 0 ; i + 128 < len ; i += 128 )
590  {
591  memcpy( xx, data + i, sizeof( uint8 ) * 128 );
592  ToCurrentEndian( x, 16 );
593  Round( H, x );
594  }
595 
596  size_type rest = len - i;
597 
598  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
599  if( rest >= 128 - 16 )
600  {
601  memcpy( xx, data + i, sizeof( uint8 ) * rest );
602  memset( xx + rest, 0, sizeof( uint8 ) * ( 128 - rest ) );
603  // 先頭のビットを 1 にする
604  xx[ rest ] = 0x80;
605 
606  // メッセージ処理を行う
607  ToCurrentEndian( x, 16 );
608  Round( H, x );
609 
610  // バイト長の分の処理を行う
611  memset( xx, 0, sizeof( uint8 ) * 128 );
612  x[ 14 ] = 0;
613  x[ 15 ] = length;
614 
615  // メッセージ処理を行う
616  Round( H, x );
617  }
618  else
619  {
620  memcpy( xx, data + i, sizeof( uint8 ) * rest );
621  memset( xx + rest, 0, sizeof( uint8 ) * ( 128 - rest ) );
622  // 先頭のビットを 1 にする
623  xx[ rest ] = 0x80;
624 
625  ToCurrentEndian( x, 16 );
626 
627  // バイト長の分の値を付加する
628  x[ 14 ] = 0;
629  x[ 15 ] = length;
630 
631  // メッセージ処理を行う
632  Round( H, x );
633  }
634 
635  FromCurrentEndian( H, 8 );
636 
637  // 文字列を左に切り詰める
638  memcpy( digest, H, size( ) );
639  }
640 
641 
643  virtual const std::string name( ) const{ return( "SHA-384" ); }
644 
645 
647  sha384( ) : base( "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" ){ }
648 
650  sha384( const std::string &str ) : base( 48 ) { base::compute_hash( str ); }
651 
653  sha384( const void *data, uint64 len ) : base( 48 ){ compute_hash( data, len ); }
654 
655 };
656 
657 
658 
659 
661 class sha512 : public hash_algorithm
662 {
663 private:
664  typedef hash_algorithm base;
665 
666 public:
669  typedef base::uint8 uint8;
672 
673 protected:
674  uint64 S( const uint64 &a, uint32 s ){ return( ( a >> s ) | ( a << ( 64 - s ) ) ); }
675  uint64 R( const uint64 &a, uint32 s ){ return( a >> s ); }
676  uint64 Ch( const uint64 &x, const uint64 &y, const uint64 &z ){ return( ( x & y ) ^ ( ~x & z ) ); }
677  uint64 Maj( const uint64 &x, const uint64 &y, const uint64 &z ){ return( ( x & y ) ^ ( x & z ) ^ ( y & z ) ); }
678  uint64 S0( const uint64 &x ){ return( S( x, 28 ) ^ S( x, 34 ) ^ S( x, 39 ) ); }
679  uint64 S1( const uint64 &x ){ return( S( x, 14 ) ^ S( x, 18 ) ^ S( x, 41 ) ); }
680  uint64 s0( const uint64 &x ){ return( S( x, 1 ) ^ S( x, 8 ) ^ R( x, 7 ) ); }
681  uint64 s1( const uint64 &x ){ return( S( x, 19 ) ^ S( x, 61 ) ^ R( x, 6 ) ); }
682 
683  void ToCurrentEndian( uint64 *x, size_type len )
684  {
685  for( size_type i = 0 ; i < len ; i++ )
686  {
687  x[ i ] = to_current_endian( byte_array< uint64 >( x[ i ] ), false ).get_value( );
688  }
689  }
690 
691  void FromCurrentEndian( uint64 *x, size_type len )
692  {
693  for( size_type i = 0 ; i < len ; i++ )
694  {
695  x[ i ] = from_current_endian( byte_array< uint64 >( x[ i ] ), false ).get_value( );
696  }
697  }
698 
699  void Round( uint64 *H, uint64 x[ 16 ] )
700  {
701  size_type i;
702  uint64 W[ 80 ];
703 
704  memcpy( W, x, sizeof( uint64 ) * 16 );
705 
706  for( i = 16 ; i < 80 ; i++ )
707  {
708  W[ i ] = s1( W[ i - 2 ] ) + W[ i - 7 ] + s0( W[ i - 15 ] ) + W[ i- 16 ];
709  }
710 
711  uint64 a = H[ 0 ];
712  uint64 b = H[ 1 ];
713  uint64 c = H[ 2 ];
714  uint64 d = H[ 3 ];
715  uint64 e = H[ 4 ];
716  uint64 f = H[ 5 ];
717  uint64 g = H[ 6 ];
718  uint64 h = H[ 7 ];
719 
720 
721  static uint64 K[] = { 4794697086780616226ULL, 8158064640168781261ULL, 13096744586834688815ULL, 16840607885511220156ULL,
722  4131703408338449720ULL, 6480981068601479193ULL, 10538285296894168987ULL, 12329834152419229976ULL,
723  15566598209576043074ULL, 1334009975649890238ULL, 2608012711638119052ULL, 6128411473006802146ULL,
724  8268148722764581231ULL, 9286055187155687089ULL, 11230858885718282805ULL, 13951009754708518548ULL,
725  16472876342353939154ULL, 17275323862435702243ULL, 1135362057144423861ULL, 2597628984639134821ULL,
726  3308224258029322869ULL, 5365058923640841347ULL, 6679025012923562964ULL, 8573033837759648693ULL,
727  10970295158949994411ULL, 12119686244451234320ULL, 12683024718118986047ULL, 13788192230050041572ULL,
728  14330467153632333762ULL, 15395433587784984357ULL, 489312712824947311ULL, 1452737877330783856ULL,
729  2861767655752347644ULL, 3322285676063803686ULL, 5560940570517711597ULL, 5996557281743188959ULL,
730  7280758554555802590ULL, 8532644243296465576ULL, 9350256976987008742ULL, 10552545826968843579ULL,
731  11727347734174303076ULL, 12113106623233404929ULL, 14000437183269869457ULL, 14369950271660146224ULL,
732  15101387698204529176ULL, 15463397548674623760ULL, 17586052441742319658ULL, 1182934255886127544ULL,
733  1847814050463011016ULL, 2177327727835720531ULL, 2830643537854262169ULL, 3796741975233480872ULL,
734  4115178125766777443ULL, 5681478168544905931ULL, 6601373596472566643ULL, 7507060721942968483ULL,
735  8399075790359081724ULL, 8693463985226723168ULL, 9568029438360202098ULL, 10144078919501101548ULL,
736  10430055236837252648ULL, 11840083180663258601ULL, 13761210420658862357ULL, 14299343276471374635ULL,
737  14566680578165727644ULL, 15097957966210449927ULL, 16922976911328602910ULL, 17689382322260857208ULL,
738  500013540394364858ULL, 748580250866718886ULL, 1242879168328830382ULL, 1977374033974150939ULL,
739  2944078676154940804ULL, 3659926193048069267ULL, 4368137639120453308ULL, 4836135668995329356ULL,
740  5532061633213252278ULL, 6448918945643986474ULL, 6902733635092675308ULL, 7801388544844847127ULL };
741 
742 
743  // ワードブロックごとの処理を行う
744  for( i = 0 ; i < 80 ; i++ )
745  {
746  uint64 T1 = h + S1( e ) + Ch( e, f, g ) + K[ i ] + W[ i ];
747  uint64 T2 = S0( a ) + Maj( a, b, c );
748  h = g;
749  g = f;
750  f = e;
751  e = d + T1;
752  d = c;
753  c = b;
754  b = a;
755  a = T1 + T2;
756  }
757 
758  H[ 0 ] += a;
759  H[ 1 ] += b;
760  H[ 2 ] += c;
761  H[ 3 ] += d;
762  H[ 4 ] += e;
763  H[ 5 ] += f;
764  H[ 6 ] += g;
765  H[ 7 ] += h;
766  }
767 
768 public:
770  virtual void compute_hash( const void *bytes, uint64 length )
771  {
772  size_type len = static_cast< size_type >( length );
773  length *= 8;
774 
775  // 出力用のダイジェストバイト列を 32 ビット単位で処理できるようにする
776  uint64 *H = reinterpret_cast< uint64 * >( digest );
777 
778  // ダイジェストバイト列の初期化
779  H[ 0 ] = 7640891576956012808ULL;
780  H[ 1 ] = 13503953896175478587ULL;
781  H[ 2 ] = 4354685564936845355ULL;
782  H[ 3 ] = 11912009170470909681ULL;
783  H[ 4 ] = 5840696475078001361ULL;
784  H[ 5 ] = 11170449401992604703ULL;
785  H[ 6 ] = 2270897969802886507ULL;
786  H[ 7 ] = 6620516959819538809ULL;
787 
788  size_type i;
789  uint64 x[ 16 ];
790  uint8 *xx = reinterpret_cast< uint8 * >( x );
791  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
792 
793  // 入力データに対してメッセージ処理を行う
794  for( i = 0 ; i + 128 < len ; i += 128 )
795  {
796  memcpy( xx, data + i, sizeof( uint8 ) * 128 );
797  ToCurrentEndian( x, 16 );
798  Round( H, x );
799  }
800 
801  size_type rest = len - i;
802 
803  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
804  if( rest >= 128 - 16 )
805  {
806  memcpy( xx, data + i, sizeof( uint8 ) * rest );
807  memset( xx + rest, 0, sizeof( uint8 ) * ( 128 - rest ) );
808  // 先頭のビットを 1 にする
809  xx[ rest ] = 0x80;
810 
811  // メッセージ処理を行う
812  ToCurrentEndian( x, 16 );
813  Round( H, x );
814 
815  // バイト長の分の処理を行う
816  memset( xx, 0, sizeof( uint8 ) * 128 );
817  x[ 14 ] = 0;
818  x[ 15 ] = length;
819 
820  // メッセージ処理を行う
821  Round( H, x );
822  }
823  else
824  {
825  memcpy( xx, data + i, sizeof( uint8 ) * rest );
826  memset( xx + rest, 0, sizeof( uint8 ) * ( 128 - rest ) );
827  // 先頭のビットを 1 にする
828  xx[ rest ] = 0x80;
829 
830  ToCurrentEndian( x, 16 );
831 
832  // バイト長の分の値を付加する
833  x[ 14 ] = 0;
834  x[ 15 ] = length;
835 
836  // メッセージ処理を行う
837  Round( H, x );
838  }
839 
840  FromCurrentEndian( reinterpret_cast< uint64 * >( digest ), 8 );
841  }
842 
843 
845  virtual const std::string name( ) const{ return( "SHA-512" ); }
846 
847 
849  sha512( ) : base( "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ){ }
850 
852  sha512( const std::string &str ) : base( 64 ) { base::compute_hash( str ); }
853 
855  sha512( const void *data, uint64 len ) : base( 64 ){ compute_hash( data, len ); }
856 
857 };
858 
859 
860 
862 // ハッシュ関数グループの終わり
863 
864 
865 // mist名前空間の終わり
866 _MIST_END
867 
868 
869 #endif // __INCLUDE_SHA__
870 

Generated on Wed Nov 12 2014 19:44:25 for MIST by doxygen 1.8.1.2