~ubuntu-branches/ubuntu/wily/liblas/wily

« back to all changes in this revision

Viewing changes to include/liblas/detail/sha1.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2009-10-02 12:36:21 UTC
  • Revision ID: james.westby@ubuntu.com-20091002123621-xrf0hhzxbwloga43
Tags: upstream-1.2.1
ImportĀ upstreamĀ versionĀ 1.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id$
 
2
//
 
3
//  sha1.h
 
4
//
 
5
//  Copyright (C) 1998
 
6
//  Paul E. Jones <paulej@arid.us>
 
7
//  All Rights Reserved.
 
8
//
 
9
//  This software is licensed as "freeware."  Permission to distribute
 
10
//  this software in source and binary forms is hereby granted without
 
11
//  a fee.  THIS SOFTWARE IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED
 
12
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
13
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
14
//  THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DAMAGES RESULTING
 
15
//  FROM THE USE OF THIS SOFTWARE, EITHER DIRECTLY OR INDIRECTLY, INCLUDING,
 
16
//  BUT NOT LIMITED TO, LOSS OF DATA OR DATA BEING RENDERED INACCURATE.
 
17
//
 
18
//////////////////////////////////////////////////////////////////////////////
 
19
//  ###Id: sha1.h,v 1.6 2004/03/27 18:02:26 paulej Exp ###
 
20
//  Modified March 7, 2007 - Andy Tompkins - change to a header only library
 
21
//////////////////////////////////////////////////////////////////////////////
 
22
//
 
23
//  Description:
 
24
//      This class implements the Secure Hashing Standard as defined
 
25
//      in FIPS PUB 180-1 published April 17, 1995.
 
26
//
 
27
//      Many of the variable names in this class, especially the single
 
28
//      character names, were used because those were the names used
 
29
//      in the publication.
 
30
//
 
31
//      The Secure Hashing Standard, which uses the Secure Hashing
 
32
//      Algorithm (SHA), produces a 160-bit message digest for a
 
33
//      given data stream.  In theory, it is highly improbable that
 
34
//      two messages will produce the same message digest.  Therefore,
 
35
//      this algorithm can serve as a means of providing a "fingerprint"
 
36
//      for a message.
 
37
//
 
38
//  Portability Issues:
 
39
//      SHA-1 is defined in terms of 32-bit "words".  This code was
 
40
//      written with the expectation that the processor has at least
 
41
//      a 32-bit machine word size.  If the machine word size is larger,
 
42
//      the code should still function properly.  One caveat to that
 
43
//      is that the input functions taking characters and character arrays
 
44
//      assume that only 8 bits of information are stored in each character.
 
45
//
 
46
//  Caveats:
 
47
//      SHA-1 is designed to work with messages less than 2^64 bits long.
 
48
//      Although SHA-1 allows a message digest to be generated for
 
49
//      messages of any number of bits less than 2^64, this implementation
 
50
//      only works with messages with a length that is a multiple of 8
 
51
//      bits.
 
52
//
 
53
#ifndef LIBLAS_SHA1_HPP_INCLUDED
 
54
#define LIBLAS_SHA1_HPP_INCLUDED
 
55
 
 
56
namespace liblas { namespace detail {
 
57
 
 
58
class SHA1
 
59
{
 
60
public:
 
61
    /*  
 
62
     *  SHA1
 
63
     *
 
64
     *  Description:
 
65
     *      This is the constructor for the sha1 class.
 
66
     *
 
67
     *  Parameters:
 
68
     *      None.
 
69
     *
 
70
     *  Returns:
 
71
     *      Nothing.
 
72
     *
 
73
     *  Comments:
 
74
     *
 
75
     */
 
76
    SHA1()
 
77
    {
 
78
        Reset();
 
79
    }
 
80
 
 
81
    /*  
 
82
     *  ~SHA1
 
83
     *
 
84
     *  Description:
 
85
     *      This is the destructor for the sha1 class
 
86
     *
 
87
     *  Parameters:
 
88
     *      None.
 
89
     *
 
90
     *  Returns:
 
91
     *      Nothing.
 
92
     *
 
93
     *  Comments:
 
94
     *
 
95
     */
 
96
    ~SHA1()
 
97
    {
 
98
        // The destructor does nothing
 
99
    }
 
100
    
 
101
    /*  
 
102
     *  Reset
 
103
     *
 
104
     *  Description:
 
105
     *      This function will initialize the sha1 class member variables
 
106
     *      in preparation for computing a new message digest.
 
107
     *
 
108
     *  Parameters:
 
109
     *      None.
 
110
     *
 
111
     *  Returns:
 
112
     *      Nothing.
 
113
     *
 
114
     *  Comments:
 
115
     *
 
116
     */
 
117
    void Reset()
 
118
    {
 
119
        Length_Low          = 0;
 
120
        Length_High         = 0;
 
121
        Message_Block_Index = 0;
 
122
    
 
123
        H[0]        = 0x67452301;
 
124
        H[1]        = 0xEFCDAB89;
 
125
        H[2]        = 0x98BADCFE;
 
126
        H[3]        = 0x10325476;
 
127
        H[4]        = 0xC3D2E1F0;
 
128
    
 
129
        Computed    = false;
 
130
        Corrupted   = false;
 
131
    }
 
132
    
 
133
    /*  
 
134
     *  Result
 
135
     *
 
136
     *  Description:
 
137
     *      This function will return the 160-bit message digest into the
 
138
     *      array provided.
 
139
     *
 
140
     *  Parameters:
 
141
     *      message_digest_array: [out]
 
142
     *          This is an array of five unsigned integers which will be filled
 
143
     *          with the message digest that has been computed.
 
144
     *
 
145
     *  Returns:
 
146
     *      True if successful, false if it failed.
 
147
     *
 
148
     *  Comments:
 
149
     *
 
150
     */
 
151
    bool Result(unsigned *message_digest_array)
 
152
    {
 
153
        int i;                                  // Counter
 
154
    
 
155
        if (Corrupted)
 
156
        {
 
157
            return false;
 
158
        }
 
159
    
 
160
        if (!Computed)
 
161
        {
 
162
            PadMessage();
 
163
            Computed = true;
 
164
        }
 
165
    
 
166
        for(i = 0; i < 5; i++)
 
167
        {
 
168
            message_digest_array[i] = H[i];
 
169
        }
 
170
    
 
171
        return true;
 
172
    }
 
173
    
 
174
    /*  
 
175
     *  Input
 
176
     *
 
177
     *  Description:
 
178
     *      This function accepts an array of octets as the next portion of
 
179
     *      the message.
 
180
     *
 
181
     *  Parameters:
 
182
     *      message_array: [in]
 
183
     *          An array of characters representing the next portion of the
 
184
     *          message.
 
185
     *
 
186
     *  Returns:
 
187
     *      Nothing.
 
188
     *
 
189
     *  Comments:
 
190
     *
 
191
     */
 
192
    void Input( const unsigned char *message_array,
 
193
                        unsigned            length)
 
194
    {
 
195
        if (!length)
 
196
        {
 
197
            return;
 
198
        }
 
199
    
 
200
        if (Computed || Corrupted)
 
201
        {
 
202
            Corrupted = true;
 
203
            return;
 
204
        }
 
205
    
 
206
        while(length-- && !Corrupted)
 
207
        {
 
208
            Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
 
209
    
 
210
            Length_Low += 8;
 
211
            Length_Low &= 0xFFFFFFFF;               // Force it to 32 bits
 
212
            if (Length_Low == 0)
 
213
            {
 
214
                Length_High++;
 
215
                Length_High &= 0xFFFFFFFF;          // Force it to 32 bits
 
216
                if (Length_High == 0)
 
217
                {
 
218
                    Corrupted = true;               // Message is too long
 
219
                }
 
220
            }
 
221
    
 
222
            if (Message_Block_Index == 64)
 
223
            {
 
224
                ProcessMessageBlock();
 
225
            }
 
226
    
 
227
            message_array++;
 
228
        }
 
229
    }
 
230
    
 
231
    /*  
 
232
     *  Input
 
233
     *
 
234
     *  Description:
 
235
     *      This function accepts an array of octets as the next portion of
 
236
     *      the message.
 
237
     *
 
238
     *  Parameters:
 
239
     *      message_array: [in]
 
240
     *          An array of characters representing the next portion of the
 
241
     *          message.
 
242
     *      length: [in]
 
243
     *          The length of the message_array
 
244
     *
 
245
     *  Returns:
 
246
     *      Nothing.
 
247
     *
 
248
     *  Comments:
 
249
     *
 
250
     */
 
251
    void Input( const char  *message_array,
 
252
                        unsigned    length)
 
253
    {
 
254
        Input((unsigned char *) message_array, length);
 
255
    }
 
256
    
 
257
    /*  
 
258
     *  Input
 
259
     *
 
260
     *  Description:
 
261
     *      This function accepts a single octets as the next message element.
 
262
     *
 
263
     *  Parameters:
 
264
     *      message_element: [in]
 
265
     *          The next octet in the message.
 
266
     *
 
267
     *  Returns:
 
268
     *      Nothing.
 
269
     *
 
270
     *  Comments:
 
271
     *
 
272
     */
 
273
    void Input(unsigned char message_element)
 
274
    {
 
275
        Input(&message_element, 1);
 
276
    }
 
277
    
 
278
    /*  
 
279
     *  Input
 
280
     *
 
281
     *  Description:
 
282
     *      This function accepts a single octet as the next message element.
 
283
     *
 
284
     *  Parameters:
 
285
     *      message_element: [in]
 
286
     *          The next octet in the message.
 
287
     *
 
288
     *  Returns:
 
289
     *      Nothing.
 
290
     *
 
291
     *  Comments:
 
292
     *
 
293
     */
 
294
    void Input(char message_element)
 
295
    {
 
296
        Input((unsigned char *) &message_element, 1);
 
297
    }
 
298
    
 
299
    /*  
 
300
     *  operator<<
 
301
     *
 
302
     *  Description:
 
303
     *      This operator makes it convenient to provide character strings to
 
304
     *      the SHA1 object for processing.
 
305
     *
 
306
     *  Parameters:
 
307
     *      message_array: [in]
 
308
     *          The character array to take as input.
 
309
     *
 
310
     *  Returns:
 
311
     *      A reference to the SHA1 object.
 
312
     *
 
313
     *  Comments:
 
314
     *      Each character is assumed to hold 8 bits of information.
 
315
     *
 
316
     */
 
317
    SHA1& operator<<(const char *message_array)
 
318
    {
 
319
        const char *p = message_array;
 
320
    
 
321
        while(*p)
 
322
        {
 
323
            Input(*p);
 
324
            p++;
 
325
        }
 
326
    
 
327
        return *this;
 
328
    }
 
329
    
 
330
    /*  
 
331
     *  operator<<
 
332
     *
 
333
     *  Description:
 
334
     *      This operator makes it convenient to provide character strings to
 
335
     *      the SHA1 object for processing.
 
336
     *
 
337
     *  Parameters:
 
338
     *      message_array: [in]
 
339
     *          The character array to take as input.
 
340
     *
 
341
     *  Returns:
 
342
     *      A reference to the SHA1 object.
 
343
     *
 
344
     *  Comments:
 
345
     *      Each character is assumed to hold 8 bits of information.
 
346
     *
 
347
     */
 
348
    SHA1& operator<<(const unsigned char *message_array)
 
349
    {
 
350
        const unsigned char *p = message_array;
 
351
    
 
352
        while(*p)
 
353
        {
 
354
            Input(*p);
 
355
            p++;
 
356
        }
 
357
    
 
358
        return *this;
 
359
    }
 
360
    
 
361
    /*  
 
362
     *  operator<<
 
363
     *
 
364
     *  Description:
 
365
     *      This function provides the next octet in the message.
 
366
     *
 
367
     *  Parameters:
 
368
     *      message_element: [in]
 
369
     *          The next octet in the message
 
370
     *
 
371
     *  Returns:
 
372
     *      A reference to the SHA1 object.
 
373
     *
 
374
     *  Comments:
 
375
     *      The character is assumed to hold 8 bits of information.
 
376
     *
 
377
     */
 
378
    SHA1& operator<<(const char message_element)
 
379
    {
 
380
        Input((unsigned char *) &message_element, 1);
 
381
    
 
382
        return *this;
 
383
    }
 
384
    
 
385
    /*  
 
386
     *  operator<<
 
387
     *
 
388
     *  Description:
 
389
     *      This function provides the next octet in the message.
 
390
     *
 
391
     *  Parameters:
 
392
     *      message_element: [in]
 
393
     *          The next octet in the message
 
394
     *
 
395
     *  Returns:
 
396
     *      A reference to the SHA1 object.
 
397
     *
 
398
     *  Comments:
 
399
     *      The character is assumed to hold 8 bits of information.
 
400
     *
 
401
     */
 
402
    SHA1& operator<<(const unsigned char message_element)
 
403
    {
 
404
        Input(&message_element, 1);
 
405
    
 
406
        return *this;
 
407
    }
 
408
    
 
409
private:
 
410
    /*  
 
411
     *  ProcessMessageBlock
 
412
     *
 
413
     *  Description:
 
414
     *      This function will process the next 512 bits of the message
 
415
     *      stored in the Message_Block array.
 
416
     *
 
417
     *  Parameters:
 
418
     *      None.
 
419
     *
 
420
     *  Returns:
 
421
     *      Nothing.
 
422
     *
 
423
     *  Comments:
 
424
     *      Many of the variable names in this function, especially the single
 
425
     *      character names, were used because those were the names used
 
426
     *      in the publication.
 
427
     *
 
428
     */
 
429
    void ProcessMessageBlock()
 
430
    {
 
431
        const unsigned K[] =    {               // Constants defined for SHA-1
 
432
                                    0x5A827999,
 
433
                                    0x6ED9EBA1,
 
434
                                    0x8F1BBCDC,
 
435
                                    0xCA62C1D6
 
436
                                };
 
437
        int         t;                          // Loop counter
 
438
        unsigned    temp;                       // Temporary word value
 
439
        unsigned    W[80];                      // Word sequence
 
440
        unsigned    A, B, C, D, E;              // Word buffers
 
441
    
 
442
        /*
 
443
         *  Initialize the first 16 words in the array W
 
444
         */
 
445
        for(t = 0; t < 16; t++)
 
446
        {
 
447
            W[t] = ((unsigned) Message_Block[t * 4]) << 24;
 
448
            W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16;
 
449
            W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8;
 
450
            W[t] |= ((unsigned) Message_Block[t * 4 + 3]);
 
451
        }
 
452
    
 
453
        for(t = 16; t < 80; t++)
 
454
        {
 
455
           W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 
456
        }
 
457
    
 
458
        A = H[0];
 
459
        B = H[1];
 
460
        C = H[2];
 
461
        D = H[3];
 
462
        E = H[4];
 
463
    
 
464
        for(t = 0; t < 20; t++)
 
465
        {
 
466
            temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
 
467
            temp &= 0xFFFFFFFF;
 
468
            E = D;
 
469
            D = C;
 
470
            C = CircularShift(30,B);
 
471
            B = A;
 
472
            A = temp;
 
473
        }
 
474
    
 
475
        for(t = 20; t < 40; t++)
 
476
        {
 
477
            temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
 
478
            temp &= 0xFFFFFFFF;
 
479
            E = D;
 
480
            D = C;
 
481
            C = CircularShift(30,B);
 
482
            B = A;
 
483
            A = temp;
 
484
        }
 
485
    
 
486
        for(t = 40; t < 60; t++)
 
487
        {
 
488
            temp = CircularShift(5,A) +
 
489
                   ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
 
490
            temp &= 0xFFFFFFFF;
 
491
            E = D;
 
492
            D = C;
 
493
            C = CircularShift(30,B);
 
494
            B = A;
 
495
            A = temp;
 
496
        }
 
497
    
 
498
        for(t = 60; t < 80; t++)
 
499
        {
 
500
            temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
 
501
            temp &= 0xFFFFFFFF;
 
502
            E = D;
 
503
            D = C;
 
504
            C = CircularShift(30,B);
 
505
            B = A;
 
506
            A = temp;
 
507
        }
 
508
    
 
509
        H[0] = (H[0] + A) & 0xFFFFFFFF;
 
510
        H[1] = (H[1] + B) & 0xFFFFFFFF;
 
511
        H[2] = (H[2] + C) & 0xFFFFFFFF;
 
512
        H[3] = (H[3] + D) & 0xFFFFFFFF;
 
513
        H[4] = (H[4] + E) & 0xFFFFFFFF;
 
514
    
 
515
        Message_Block_Index = 0;
 
516
    }
 
517
    
 
518
    /*  
 
519
     *  PadMessage
 
520
     *
 
521
     *  Description:
 
522
     *      According to the standard, the message must be padded to an even
 
523
     *      512 bits.  The first padding bit must be a '1'.  The last 64 bits
 
524
     *      represent the length of the original message.  All bits in between
 
525
     *      should be 0.  This function will pad the message according to those
 
526
     *      rules by filling the message_block array accordingly.  It will also
 
527
     *      call ProcessMessageBlock() appropriately.  When it returns, it
 
528
     *      can be assumed that the message digest has been computed.
 
529
     *
 
530
     *  Parameters:
 
531
     *      None.
 
532
     *
 
533
     *  Returns:
 
534
     *      Nothing.
 
535
     *
 
536
     *  Comments:
 
537
     *
 
538
     */
 
539
    void PadMessage()
 
540
    {
 
541
        /*
 
542
         *  Check to see if the current message block is too small to hold
 
543
         *  the initial padding bits and length.  If so, we will pad the
 
544
         *  block, process it, and then continue padding into a second block.
 
545
         */
 
546
        if (Message_Block_Index > 55)
 
547
        {
 
548
            Message_Block[Message_Block_Index++] = 0x80;
 
549
            while(Message_Block_Index < 64)
 
550
            {
 
551
                Message_Block[Message_Block_Index++] = 0;
 
552
            }
 
553
    
 
554
            ProcessMessageBlock();
 
555
    
 
556
            while(Message_Block_Index < 56)
 
557
            {
 
558
                Message_Block[Message_Block_Index++] = 0;
 
559
            }
 
560
        }
 
561
        else
 
562
        {
 
563
            Message_Block[Message_Block_Index++] = 0x80;
 
564
            while(Message_Block_Index < 56)
 
565
            {
 
566
                Message_Block[Message_Block_Index++] = 0;
 
567
            }
 
568
    
 
569
        }
 
570
    
 
571
        /*
 
572
         *  Store the message length as the last 8 octets
 
573
         */
 
574
        Message_Block[56] = static_cast<unsigned char>((Length_High >> 24) & 0xFF);
 
575
        Message_Block[57] = static_cast<unsigned char>((Length_High >> 16) & 0xFF);
 
576
        Message_Block[58] = static_cast<unsigned char>((Length_High >> 8) & 0xFF);
 
577
        Message_Block[59] = static_cast<unsigned char>((Length_High) & 0xFF);
 
578
        Message_Block[60] = static_cast<unsigned char>((Length_Low >> 24) & 0xFF);
 
579
        Message_Block[61] = static_cast<unsigned char>((Length_Low >> 16) & 0xFF);
 
580
        Message_Block[62] = static_cast<unsigned char>((Length_Low >> 8) & 0xFF);
 
581
        Message_Block[63] = static_cast<unsigned char>((Length_Low) & 0xFF);
 
582
    
 
583
        ProcessMessageBlock();
 
584
    }
 
585
    
 
586
    
 
587
    /*  
 
588
     *  CircularShift
 
589
     *
 
590
     *  Description:
 
591
     *      This member function will perform a circular shifting operation.
 
592
     *
 
593
     *  Parameters:
 
594
     *      bits: [in]
 
595
     *          The number of bits to shift (1-31)
 
596
     *      word: [in]
 
597
     *          The value to shift (assumes a 32-bit integer)
 
598
     *
 
599
     *  Returns:
 
600
     *      The shifted value.
 
601
     *
 
602
     *  Comments:
 
603
     *
 
604
     */
 
605
    unsigned CircularShift(int bits, unsigned word)
 
606
    {
 
607
        return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
 
608
    }
 
609
    
 
610
private:
 
611
    unsigned H[5];                      // Message digest buffers
 
612
 
 
613
    unsigned Length_Low;                // Message length in bits
 
614
    unsigned Length_High;               // Message length in bits
 
615
 
 
616
    unsigned char Message_Block[64];    // 512-bit message blocks
 
617
    int Message_Block_Index;            // Index into message block array
 
618
 
 
619
    bool Computed;                      // Is the digest computed?
 
620
    bool Corrupted;                     // Is the message digest corruped?
 
621
};
 
622
 
 
623
}} //namespace liblas::detail
 
624
    
 
625
#endif // LIBLAS_SHA1_HPP_INCLUDED