Mercurial > projects > dcrypt
comparison dcrypt/crypto/hashes/SHA1.d @ 27:8b5eaf3c2979
Fixed error in hash message padding reported by Glenn Haecker.
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Sat, 09 May 2009 23:29:20 -0400 |
parents | 176c933827a8 |
children | ad687db713a4 |
comparison
equal
deleted
inserted
replaced
26:176c933827a8 | 27:8b5eaf3c2979 |
---|---|
15 * | 15 * |
16 * Conforms: FIPS 180-1 | 16 * Conforms: FIPS 180-1 |
17 * References: http://www.itl.nist.gov/fipspubs/fip180-1.htm | 17 * References: http://www.itl.nist.gov/fipspubs/fip180-1.htm |
18 * Bugs: SHA-1 is not cryptographically secure. | 18 * Bugs: SHA-1 is not cryptographically secure. |
19 */ | 19 */ |
20 class SHA1 : Hash { | 20 class SHA1 : Hash |
21 { | |
21 protected uint h0, h1, h2, h3, h4; | 22 protected uint h0, h1, h2, h3, h4; |
22 | 23 |
23 this (void[] input_=null) { | 24 this (void[] input_=null) |
25 { | |
24 reset(); | 26 reset(); |
25 super(input_); | 27 super(input_); |
26 } | 28 } |
27 | 29 |
28 uint blockSize() { | 30 uint blockSize() |
31 { | |
29 return 64; | 32 return 64; |
30 } | 33 } |
31 | 34 |
32 uint digestSize() { | 35 uint digestSize() |
36 { | |
33 return 20; | 37 return 20; |
34 } | 38 } |
35 | 39 |
36 char[] name() { | 40 char[] name() |
41 { | |
37 return "SHA1"; | 42 return "SHA1"; |
38 } | 43 } |
39 | 44 |
40 void transform(ubyte[] input) { | 45 void transform(ubyte[] input) |
46 { | |
41 uint[] w = new uint[80]; | 47 uint[] w = new uint[80]; |
42 | 48 |
43 for (int i = 0, j = 0; i < 16; i++,j+=int.sizeof) | 49 for (int i = 0, j = 0; i < 16; i++,j+=int.sizeof) |
44 w[i] = ByteConverter.BigEndian.to!(uint)(input[j..j+int.sizeof]); | 50 w[i] = ByteConverter.BigEndian.to!(uint)(input[j..j+int.sizeof]); |
45 | 51 |
51 c = h2, | 57 c = h2, |
52 d = h3, | 58 d = h3, |
53 e = h4; | 59 e = h4; |
54 | 60 |
55 int i = 0; | 61 int i = 0; |
56 for (; i < 20;) { | 62 for (; i < 20;) |
63 { | |
57 e += Bitwise.rotateLeft(a, 5) + f0(b, c, d) + w[i++]; | 64 e += Bitwise.rotateLeft(a, 5) + f0(b, c, d) + w[i++]; |
58 b = Bitwise.rotateLeft(b, 30); | 65 b = Bitwise.rotateLeft(b, 30); |
59 | 66 |
60 d += Bitwise.rotateLeft(e, 5) + f0(a, b, c) + w[i++]; | 67 d += Bitwise.rotateLeft(e, 5) + f0(a, b, c) + w[i++]; |
61 a = Bitwise.rotateLeft(a, 30); | 68 a = Bitwise.rotateLeft(a, 30); |
68 | 75 |
69 a += Bitwise.rotateLeft(b, 5) + f0(c, d, e) + w[i++]; | 76 a += Bitwise.rotateLeft(b, 5) + f0(c, d, e) + w[i++]; |
70 c = Bitwise.rotateLeft(c, 30); | 77 c = Bitwise.rotateLeft(c, 30); |
71 } | 78 } |
72 | 79 |
73 for (; i < 40;) { | 80 for (; i < 40;) |
81 { | |
74 e += Bitwise.rotateLeft(a, 5) + f1(b, c, d) + w[i++]; | 82 e += Bitwise.rotateLeft(a, 5) + f1(b, c, d) + w[i++]; |
75 b = Bitwise.rotateLeft(b, 30); | 83 b = Bitwise.rotateLeft(b, 30); |
76 | 84 |
77 d += Bitwise.rotateLeft(e, 5) + f1(a, b, c) + w[i++]; | 85 d += Bitwise.rotateLeft(e, 5) + f1(a, b, c) + w[i++]; |
78 a = Bitwise.rotateLeft(a, 30); | 86 a = Bitwise.rotateLeft(a, 30); |
85 | 93 |
86 a += Bitwise.rotateLeft(b, 5) + f1(c, d, e) + w[i++]; | 94 a += Bitwise.rotateLeft(b, 5) + f1(c, d, e) + w[i++]; |
87 c = Bitwise.rotateLeft(c, 30); | 95 c = Bitwise.rotateLeft(c, 30); |
88 } | 96 } |
89 | 97 |
90 for (; i < 60;) { | 98 for (; i < 60;) |
99 { | |
91 e += Bitwise.rotateLeft(a, 5) + f2(b, c, d) + w[i++]; | 100 e += Bitwise.rotateLeft(a, 5) + f2(b, c, d) + w[i++]; |
92 b = Bitwise.rotateLeft(b, 30); | 101 b = Bitwise.rotateLeft(b, 30); |
93 | 102 |
94 d += Bitwise.rotateLeft(e, 5) + f2(a, b, c) + w[i++]; | 103 d += Bitwise.rotateLeft(e, 5) + f2(a, b, c) + w[i++]; |
95 a = Bitwise.rotateLeft(a, 30); | 104 a = Bitwise.rotateLeft(a, 30); |
102 | 111 |
103 a += Bitwise.rotateLeft(b, 5) + f2(c, d, e) + w[i++]; | 112 a += Bitwise.rotateLeft(b, 5) + f2(c, d, e) + w[i++]; |
104 c = Bitwise.rotateLeft(c, 30); | 113 c = Bitwise.rotateLeft(c, 30); |
105 } | 114 } |
106 | 115 |
107 for (; i < 80;) { | 116 for (; i < 80;) |
117 { | |
108 e += Bitwise.rotateLeft(a, 5) + f3(b, c, d) + w[i++]; | 118 e += Bitwise.rotateLeft(a, 5) + f3(b, c, d) + w[i++]; |
109 b = Bitwise.rotateLeft(b, 30); | 119 b = Bitwise.rotateLeft(b, 30); |
110 | 120 |
111 d += Bitwise.rotateLeft(e, 5) + f3(a, b, c) + w[i++]; | 121 d += Bitwise.rotateLeft(e, 5) + f3(a, b, c) + w[i++]; |
112 a = Bitwise.rotateLeft(a, 30); | 122 a = Bitwise.rotateLeft(a, 30); |
126 h2 += c; | 136 h2 += c; |
127 h3 += d; | 137 h3 += d; |
128 h4 += e; | 138 h4 += e; |
129 } | 139 } |
130 | 140 |
131 private uint f0(uint x, uint y, uint z) { | 141 private uint f0(uint x, uint y, uint z) |
142 { | |
132 return (z^(x&(y^z))) + 0x5a827999; | 143 return (z^(x&(y^z))) + 0x5a827999; |
133 } | 144 } |
134 | 145 |
135 private uint f1(uint x, uint y, uint z) { | 146 private uint f1(uint x, uint y, uint z) |
147 { | |
136 return (x^y^z) + 0x6ed9eba1; | 148 return (x^y^z) + 0x6ed9eba1; |
137 } | 149 } |
138 | 150 |
139 private uint f2(uint x, uint y, uint z) { | 151 private uint f2(uint x, uint y, uint z) |
152 { | |
140 return ((x&y)|(z&(x|y))) + 0x8f1bbcdc; | 153 return ((x&y)|(z&(x|y))) + 0x8f1bbcdc; |
141 } | 154 } |
142 | 155 |
143 private uint f3(uint x, uint y, uint z) { | 156 private uint f3(uint x, uint y, uint z) |
157 { | |
144 return (x^y^z) + 0xca62c1d6; | 158 return (x^y^z) + 0xca62c1d6; |
145 } | 159 } |
146 | 160 |
147 ubyte[] digest() { | 161 ubyte[] digest() |
162 { | |
148 padMessage(MODE_SHA); | 163 padMessage(MODE_SHA); |
149 ubyte[] result = new ubyte[digestSize]; | 164 ubyte[] result = new ubyte[digestSize]; |
150 | 165 |
151 result[0..4] = ByteConverter.BigEndian.from!(uint)(h0); | 166 result[0..4] = ByteConverter.BigEndian.from!(uint)(h0); |
152 result[4..8] = ByteConverter.BigEndian.from!(uint)(h1); | 167 result[4..8] = ByteConverter.BigEndian.from!(uint)(h1); |
156 | 171 |
157 reset(); | 172 reset(); |
158 return result; | 173 return result; |
159 } | 174 } |
160 | 175 |
161 void reset() { | 176 void reset() |
177 { | |
162 super.reset(); | 178 super.reset(); |
163 h0 = 0x67452301u; | 179 h0 = 0x67452301u; |
164 h1 = 0xefcdab89u; | 180 h1 = 0xefcdab89u; |
165 h2 = 0x98badcfeu; | 181 h2 = 0x98badcfeu; |
166 h3 = 0x10325476u; | 182 h3 = 0x10325476u; |
167 h4 = 0xc3d2e1f0u; | 183 h4 = 0xc3d2e1f0u; |
168 } | 184 } |
169 | 185 |
170 SHA1 copy() { | 186 SHA1 copy() |
187 { | |
171 SHA1 h = new SHA1(buffer[0..index]); | 188 SHA1 h = new SHA1(buffer[0..index]); |
172 h.bytes = bytes; | 189 h.bytes = bytes; |
173 h.h0 = h0; | 190 h.h0 = h0; |
174 h.h1 = h1; | 191 h.h1 = h1; |
175 h.h2 = h2; | 192 h.h2 = h2; |
176 h.h3 = h3; | 193 h.h3 = h3; |
177 h.h4 = h4; | 194 h.h4 = h4; |
178 return h; | 195 return h; |
179 } | 196 } |
180 | 197 |
181 debug (UnitTest) { | 198 debug (UnitTest) |
182 unittest { | 199 { |
200 unittest | |
201 { | |
183 static const char[][] test_inputs = [ | 202 static const char[][] test_inputs = [ |
184 "", | 203 "", |
185 "abc", | 204 "abc", |
186 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | 205 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", |
187 "a", | 206 "a", |
199 "34aa973cd4c4daa4f61eeb2bdbad27316534016f", | 218 "34aa973cd4c4daa4f61eeb2bdbad27316534016f", |
200 "dea356a2cddd90c7a7ecedc5ebb563934f460452" | 219 "dea356a2cddd90c7a7ecedc5ebb563934f460452" |
201 ]; | 220 ]; |
202 | 221 |
203 SHA1 h = new SHA1(); | 222 SHA1 h = new SHA1(); |
204 foreach (uint i, char[] input; test_inputs) { | 223 foreach (uint i, char[] input; test_inputs) |
224 { | |
205 for (int j = 0; j < test_repeat[i]; j++) | 225 for (int j = 0; j < test_repeat[i]; j++) |
206 h.update(input); | 226 h.update(input); |
207 char[] digest = h.hexDigest(); | 227 char[] digest = h.hexDigest(); |
208 assert(digest == test_results[i], | 228 assert(digest == test_results[i], |
209 h.name~": ("~digest~") != ("~test_results[i]~")"); | 229 h.name~": ("~digest~") != ("~test_results[i]~")"); |