aboutsummaryrefslogtreecommitdiff
path: root/src/sha1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sha1.cpp')
-rw-r--r--src/sha1.cpp161
1 files changed, 0 insertions, 161 deletions
diff --git a/src/sha1.cpp b/src/sha1.cpp
deleted file mode 100644
index 8270c3b..0000000
--- a/src/sha1.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#include "sha1.h"
6
7Sha1::Sha1() :
8 H0( 0x67452301 ),
9 H1( 0xefcdab89 ),
10 H2( 0x98badcfe ),
11 H3( 0x10325476 ),
12 H4( 0xc3d2e1f0 ),
13 unprocessedBytes( 0 ),
14 size( 0 )
15{
16}
17
18Sha1::~Sha1()
19{
20}
21
22void Sha1::process()
23{
24 int t;
25 uint32_t a, b, c, d, e, K, f, W[80];
26
27 // starting values
28 a = H0;
29 b = H1;
30 c = H2;
31 d = H3;
32 e = H4;
33
34 // copy and expand the message block
35 for( t = 0; t < 16; t++ ) W[t] = (bytes[t*4] << 24)
36 +(bytes[t*4 + 1] << 16)
37 +(bytes[t*4 + 2] << 8)
38 + bytes[t*4 + 3];
39 for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 );
40
41 /* main loop */
42 uint32_t temp;
43 for( t = 0; t < 80; t++ )
44 {
45 if( t < 20 ) {
46 K = 0x5a827999;
47 f = (b & c) | ((~b) & d);
48 } else if( t < 40 ) {
49 K = 0x6ed9eba1;
50 f = b ^ c ^ d;
51 } else if( t < 60 ) {
52 K = 0x8f1bbcdc;
53 f = (b & c) | (b & d) | (c & d);
54 } else {
55 K = 0xca62c1d6;
56 f = b ^ c ^ d;
57 }
58 temp = lrot(a,5) + f + e + W[t] + K;
59 e = d;
60 d = c;
61 c = lrot(b,30);
62 b = a;
63 a = temp;
64 //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e );
65 }
66
67 /* add variables */
68 H0 += a;
69 H1 += b;
70 H2 += c;
71 H3 += d;
72 H4 += e;
73
74 //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 );
75 /* all bytes have been processed */
76 unprocessedBytes = 0;
77}
78
79void Sha1::update( const char* data, int num )
80{
81 // add these bytes to the running total
82 size += num;
83
84 // repeat until all data is processed
85 while( num > 0 )
86 {
87 // number of bytes required to complete block
88 int needed = 64 - unprocessedBytes;
89
90 // number of bytes to copy (use smaller of two)
91 int toCopy = (num < needed) ? num : needed;
92
93 // Copy the bytes
94 memcpy( bytes + unprocessedBytes, data, toCopy );
95
96 // Bytes have been copied
97 num -= toCopy;
98 data += toCopy;
99 unprocessedBytes += toCopy;
100
101 // there is a full block
102 if( unprocessedBytes == 64 ) process();
103 }
104}
105
106unsigned char* Sha1::getDigest()
107{
108 // save the message size
109 uint32_t totalBitsL = size << 3;
110 uint32_t totalBitsH = size >> 29;
111
112 // add 0x80 to the message
113 update( "\x80", 1 );
114
115 unsigned char footer[64] = {
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
120
121 // block has no room for 8-byte filesize, so finish it
122 if( unprocessedBytes > 56 )
123 update( (char*)footer, 64 - unprocessedBytes);
124
125 // how many zeros do we need
126 int neededZeros = 56 - unprocessedBytes;
127
128 // store file size (in bits) in big-endian format
129 toBigEndian( totalBitsH, footer + neededZeros );
130 toBigEndian( totalBitsL, footer + neededZeros + 4 );
131
132 // finish the final block
133 update( (char*)footer, neededZeros + 8 );
134
135 // allocate memory for the digest bytes
136 unsigned char* digest = new unsigned char[20];
137
138 // copy the digest bytes
139 toBigEndian( H0, digest );
140 toBigEndian( H1, digest + 4 );
141 toBigEndian( H2, digest + 8 );
142 toBigEndian( H3, digest + 12 );
143 toBigEndian( H4, digest + 16 );
144
145 // return the digest
146 return digest;
147}
148
149uint32_t Sha1::lrot( uint32_t x, int bits )
150{
151 return (x<<bits) | (x>>(32 - bits));
152};
153
154void Sha1::toBigEndian( uint32_t num, unsigned char* byte )
155{
156 byte[0] = (unsigned char)(num>>24);
157 byte[1] = (unsigned char)(num>>16);
158 byte[2] = (unsigned char)(num>>8);
159 byte[3] = (unsigned char)num;
160}
161