diff options
author | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2012-03-25 20:00:08 +0000 |
commit | 469bbcf0701e1eb8a6670c23145b0da87357e178 (patch) | |
tree | b5b062a16e46a6c5d3410b4e574cd0cc09057211 /src/stable/sha1.cpp | |
parent | ee1b79396076edc4e30aefb285fada03bb45e80d (diff) | |
download | libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.gz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.bz2 libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.tar.xz libbu++-469bbcf0701e1eb8a6670c23145b0da87357e178.zip |
Code is all reorganized. We're about ready to release. I should write up a
little explenation of the arrangement.
Diffstat (limited to 'src/stable/sha1.cpp')
-rw-r--r-- | src/stable/sha1.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/stable/sha1.cpp b/src/stable/sha1.cpp new file mode 100644 index 0000000..bfe4c5a --- /dev/null +++ b/src/stable/sha1.cpp | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2011 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #include <string.h> | ||
9 | |||
10 | #include "bu/stream.h" | ||
11 | |||
12 | #include "bu/sha1.h" | ||
13 | |||
14 | Bu::Sha1::Sha1() : | ||
15 | uH0( 0x67452301 ), | ||
16 | uH1( 0xefcdab89 ), | ||
17 | uH2( 0x98badcfe ), | ||
18 | uH3( 0x10325476 ), | ||
19 | uH4( 0xc3d2e1f0 ), | ||
20 | iUnprocessedBytes( 0 ), | ||
21 | uTotalBytes( 0 ) | ||
22 | { | ||
23 | reset(); | ||
24 | } | ||
25 | |||
26 | Bu::Sha1::~Sha1() | ||
27 | { | ||
28 | } | ||
29 | |||
30 | void Bu::Sha1::reset() | ||
31 | { | ||
32 | uH0 = 0x67452301; | ||
33 | uH1 = 0xefcdab89; | ||
34 | uH2 = 0x98badcfe; | ||
35 | uH3 = 0x10325476; | ||
36 | uH4 = 0xc3d2e1f0; | ||
37 | iUnprocessedBytes = 0; | ||
38 | uTotalBytes = 0; | ||
39 | } | ||
40 | |||
41 | void Bu::Sha1::setSalt( const Bu::String & /*sSalt*/ ) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | void Bu::Sha1::addData( const void *sDataRaw, int iSize ) | ||
46 | { | ||
47 | const unsigned char *sData = (const unsigned char *)sDataRaw; | ||
48 | // add these bytes to the running total | ||
49 | uTotalBytes += iSize; | ||
50 | |||
51 | // repeat until all data is processed | ||
52 | while( iSize > 0 ) | ||
53 | { | ||
54 | // number of bytes required to complete block | ||
55 | int iNeeded = 64 - iUnprocessedBytes; | ||
56 | |||
57 | // number of bytes to copy (use smaller of two) | ||
58 | int iToCopy = (iSize < iNeeded) ? iSize : iNeeded; | ||
59 | |||
60 | // Copy the bytes | ||
61 | memcpy( uBytes + iUnprocessedBytes, sData, iToCopy ); | ||
62 | |||
63 | // Bytes have been copied | ||
64 | iSize -= iToCopy; | ||
65 | sData += iToCopy; | ||
66 | iUnprocessedBytes += iToCopy; | ||
67 | |||
68 | // there is a full block | ||
69 | if( iUnprocessedBytes == 64 ) | ||
70 | { | ||
71 | process(); | ||
72 | } | ||
73 | } | ||
74 | } | ||
75 | |||
76 | Bu::String Bu::Sha1::getResult() | ||
77 | { | ||
78 | // save the message size | ||
79 | uint32_t totalBitsL = uTotalBytes << 3; | ||
80 | uint32_t totalBitsH = uTotalBytes >> 29; | ||
81 | |||
82 | // add 0x80 to the message | ||
83 | addData( "\x80", 1 ); | ||
84 | |||
85 | unsigned char footer[64] = { | ||
86 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
87 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
88 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
89 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
90 | |||
91 | // block has no room for 8-byte filesize, so finish it | ||
92 | if( iUnprocessedBytes > 56 ) | ||
93 | addData( (char*)footer, 64 - iUnprocessedBytes); | ||
94 | |||
95 | // how many zeros do we need | ||
96 | int iNeededZeros = 56 - iUnprocessedBytes; | ||
97 | |||
98 | // store file size (in bits) in big-endian format | ||
99 | toBigEndian( totalBitsH, footer + iNeededZeros ); | ||
100 | toBigEndian( totalBitsL, footer + iNeededZeros + 4 ); | ||
101 | |||
102 | // finish the final block | ||
103 | addData( (char*)footer, iNeededZeros + 8 ); | ||
104 | |||
105 | Bu::String sRet( 20 ); | ||
106 | |||
107 | unsigned char *digest = (unsigned char *)sRet.getStr(); | ||
108 | |||
109 | // copy the digest bytes | ||
110 | toBigEndian( uH0, digest ); | ||
111 | toBigEndian( uH1, digest + 4 ); | ||
112 | toBigEndian( uH2, digest + 8 ); | ||
113 | toBigEndian( uH3, digest + 12 ); | ||
114 | toBigEndian( uH4, digest + 16 ); | ||
115 | |||
116 | // return the digest | ||
117 | return sRet; | ||
118 | } | ||
119 | |||
120 | void Bu::Sha1::writeResult( Bu::Stream &sOut ) | ||
121 | { | ||
122 | sOut.write( getResult() ); | ||
123 | } | ||
124 | |||
125 | void Bu::Sha1::process() | ||
126 | { | ||
127 | int t; | ||
128 | uint32_t a, b, c, d, e, K, f, W[80]; | ||
129 | |||
130 | // starting values | ||
131 | a = uH0; | ||
132 | b = uH1; | ||
133 | c = uH2; | ||
134 | d = uH3; | ||
135 | e = uH4; | ||
136 | |||
137 | // copy and expand the message block | ||
138 | for( t = 0; t < 16; t++ ) W[t] = (uBytes[t*4] << 24) | ||
139 | +(uBytes[t*4 + 1] << 16) | ||
140 | +(uBytes[t*4 + 2] << 8) | ||
141 | + uBytes[t*4 + 3]; | ||
142 | for(; t< 80; t++ ) W[t] = lrot( W[t-3]^W[t-8]^W[t-14]^W[t-16], 1 ); | ||
143 | |||
144 | /* main loop */ | ||
145 | uint32_t temp; | ||
146 | for( t = 0; t < 80; t++ ) | ||
147 | { | ||
148 | if( t < 20 ) { | ||
149 | K = 0x5a827999; | ||
150 | f = (b & c) | ((~b) & d); | ||
151 | } else if( t < 40 ) { | ||
152 | K = 0x6ed9eba1; | ||
153 | f = b ^ c ^ d; | ||
154 | } else if( t < 60 ) { | ||
155 | K = 0x8f1bbcdc; | ||
156 | f = (b & c) | (b & d) | (c & d); | ||
157 | } else { | ||
158 | K = 0xca62c1d6; | ||
159 | f = b ^ c ^ d; | ||
160 | } | ||
161 | temp = lrot(a,5) + f + e + W[t] + K; | ||
162 | e = d; | ||
163 | d = c; | ||
164 | c = lrot(b,30); | ||
165 | b = a; | ||
166 | a = temp; | ||
167 | //printf( "t=%d %08x %08x %08x %08x %08x\n",t,a,b,c,d,e ); | ||
168 | } | ||
169 | |||
170 | /* add variables */ | ||
171 | uH0 += a; | ||
172 | uH1 += b; | ||
173 | uH2 += c; | ||
174 | uH3 += d; | ||
175 | uH4 += e; | ||
176 | |||
177 | //printf( "Current: %08x %08x %08x %08x %08x\n",H0,H1,H2,H3,H4 ); | ||
178 | /* all bytes have been processed */ | ||
179 | iUnprocessedBytes = 0; | ||
180 | } | ||
181 | |||
182 | uint32_t Bu::Sha1::lrot( uint32_t x, int bits ) | ||
183 | { | ||
184 | return (x<<bits) | (x>>(32 - bits)); | ||
185 | } | ||
186 | |||
187 | void Bu::Sha1::toBigEndian( uint32_t num, unsigned char* byte ) | ||
188 | { | ||
189 | byte[0] = (unsigned char)(num>>24); | ||
190 | byte[1] = (unsigned char)(num>>16); | ||
191 | byte[2] = (unsigned char)(num>>8); | ||
192 | byte[3] = (unsigned char)num; | ||
193 | } | ||
194 | |||