Mercurial > projects > dcrypt
annotate dcrypt/crypto/hashes/SHA1.d @ 3:a5789a7b3b3b
Fixed error in hash copy() functions where I forgot to copy the length of the message. Now, twice as jank! =)
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Thu, 14 Aug 2008 01:13:26 -0400 |
parents | 71aae178f89a |
children | 5cb17e09d685 |
rev | line source |
---|---|
0 | 1 /** |
2 * This file is part of the dcrypt project. | |
3 * | |
4 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved. | |
5 * License: MIT | |
6 * Authors: Thomas Dixon | |
7 */ | |
8 | |
9 module dcrypt.crypto.hashes.SHA1; | |
10 | |
11 public import dcrypt.crypto.Hash; | |
12 | |
13 /** Implementation of SHA-1. */ | |
14 class SHA1 : Hash { | |
2
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
15 protected uint h0, h1, h2, h3, h4; |
0 | 16 |
17 this (void[] input_=null) { | |
18 reset(); | |
19 super(input_); | |
20 } | |
21 | |
22 uint blockSize() { | |
23 return 64; | |
24 } | |
25 | |
26 uint digestSize() { | |
27 return 20; | |
28 } | |
29 | |
30 char[] name() { | |
31 return "SHA1"; | |
32 } | |
33 | |
34 void transform(ubyte[] input) { | |
35 uint[] w = new uint[80]; | |
36 | |
37 for (int i = 0, j = 0; i < 16; i++,j+=4) | |
38 w[i] = Util.ubytesToUintBig(input, j); | |
39 | |
40 for (int i = 16; i < 80; i++) | |
41 w[i] = Util.rotateLeft(w[i-3]^w[i-8]^w[i-14]^w[i-16], 1); | |
42 | |
43 uint a = h0, | |
44 b = h1, | |
45 c = h2, | |
46 d = h3, | |
47 e = h4; | |
48 | |
49 int i = 0; | |
50 for (; i < 20;) { | |
51 e += Util.rotateLeft(a, 5) + f0(b, c, d) + w[i++]; | |
52 b = Util.rotateLeft(b, 30); | |
53 | |
54 d += Util.rotateLeft(e, 5) + f0(a, b, c) + w[i++]; | |
55 a = Util.rotateLeft(a, 30); | |
56 | |
57 c += Util.rotateLeft(d, 5) + f0(e, a, b) + w[i++]; | |
58 e = Util.rotateLeft(e, 30); | |
59 | |
60 b += Util.rotateLeft(c, 5) + f0(d, e, a) + w[i++]; | |
61 d = Util.rotateLeft(d, 30); | |
62 | |
63 a += Util.rotateLeft(b, 5) + f0(c, d, e) + w[i++]; | |
64 c = Util.rotateLeft(c, 30); | |
65 } | |
66 | |
67 for (; i < 40;) { | |
68 e += Util.rotateLeft(a, 5) + f1(b, c, d) + w[i++]; | |
69 b = Util.rotateLeft(b, 30); | |
70 | |
71 d += Util.rotateLeft(e, 5) + f1(a, b, c) + w[i++]; | |
72 a = Util.rotateLeft(a, 30); | |
73 | |
74 c += Util.rotateLeft(d, 5) + f1(e, a, b) + w[i++]; | |
75 e = Util.rotateLeft(e, 30); | |
76 | |
77 b += Util.rotateLeft(c, 5) + f1(d, e, a) + w[i++]; | |
78 d = Util.rotateLeft(d, 30); | |
79 | |
80 a += Util.rotateLeft(b, 5) + f1(c, d, e) + w[i++]; | |
81 c = Util.rotateLeft(c, 30); | |
82 } | |
83 | |
84 for (; i < 60;) { | |
85 e += Util.rotateLeft(a, 5) + f2(b, c, d) + w[i++]; | |
86 b = Util.rotateLeft(b, 30); | |
87 | |
88 d += Util.rotateLeft(e, 5) + f2(a, b, c) + w[i++]; | |
89 a = Util.rotateLeft(a, 30); | |
90 | |
91 c += Util.rotateLeft(d, 5) + f2(e, a, b) + w[i++]; | |
92 e = Util.rotateLeft(e, 30); | |
93 | |
94 b += Util.rotateLeft(c, 5) + f2(d, e, a) + w[i++]; | |
95 d = Util.rotateLeft(d, 30); | |
96 | |
97 a += Util.rotateLeft(b, 5) + f2(c, d, e) + w[i++]; | |
98 c = Util.rotateLeft(c, 30); | |
99 } | |
100 | |
101 for (; i < 80;) { | |
102 e += Util.rotateLeft(a, 5) + f3(b, c, d) + w[i++]; | |
103 b = Util.rotateLeft(b, 30); | |
104 | |
105 d += Util.rotateLeft(e, 5) + f3(a, b, c) + w[i++]; | |
106 a = Util.rotateLeft(a, 30); | |
107 | |
108 c += Util.rotateLeft(d, 5) + f3(e, a, b) + w[i++]; | |
109 e = Util.rotateLeft(e, 30); | |
110 | |
111 b += Util.rotateLeft(c, 5) + f3(d, e, a) + w[i++]; | |
112 d = Util.rotateLeft(d, 30); | |
113 | |
114 a += Util.rotateLeft(b, 5) + f3(c, d, e) + w[i++]; | |
115 c = Util.rotateLeft(c, 30); | |
116 } | |
117 | |
118 h0 += a; | |
119 h1 += b; | |
120 h2 += c; | |
121 h3 += d; | |
122 h4 += e; | |
123 } | |
124 | |
125 private uint f0(uint x, uint y, uint z) { | |
126 return (z^(x&(y^z))) + 0x5a827999; | |
127 } | |
128 | |
129 private uint f1(uint x, uint y, uint z) { | |
130 return (x^y^z) + 0x6ed9eba1; | |
131 } | |
132 | |
133 private uint f2(uint x, uint y, uint z) { | |
134 return ((x&y)|(z&(x|y))) + 0x8f1bbcdc; | |
135 } | |
136 | |
137 private uint f3(uint x, uint y, uint z) { | |
138 return (x^y^z) + 0xca62c1d6; | |
139 } | |
140 | |
141 ubyte[] digest() { | |
142 padMessage(MODE_SHA); | |
143 ubyte[] result = new ubyte[digestSize]; | |
144 | |
145 Util.uintToUbytesBig(h0, result, 0); | |
146 Util.uintToUbytesBig(h1, result, 4); | |
147 Util.uintToUbytesBig(h2, result, 8); | |
148 Util.uintToUbytesBig(h3, result, 12); | |
149 Util.uintToUbytesBig(h4, result, 16); | |
150 | |
151 reset(); | |
152 return result; | |
153 } | |
154 | |
155 void reset() { | |
156 super.reset(); | |
157 h0 = 0x67452301u; | |
158 h1 = 0xefcdab89u; | |
159 h2 = 0x98badcfeu; | |
160 h3 = 0x10325476u; | |
161 h4 = 0xc3d2e1f0u; | |
162 } | |
163 | |
2
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
164 SHA1 copy() { |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
165 SHA1 h = new SHA1(buffer[0..index]); |
3
a5789a7b3b3b
Fixed error in hash copy() functions where I forgot to copy the length of the message. Now, twice as jank! =)
Thomas Dixon <reikon@reikon.us>
parents:
2
diff
changeset
|
166 h.bytes = bytes; |
2
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
167 h.h0 = h0; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
168 h.h1 = h1; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
169 h.h2 = h2; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
170 h.h3 = h3; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
171 h.h4 = h4; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
172 return h; |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
173 } |
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
174 |
0 | 175 version (UnitTest) { |
176 unittest { | |
177 static const char[][] test_inputs = [ | |
178 "", | |
179 "abc", | |
180 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | |
181 "a", | |
182 "0123456701234567012345670123456701234567012345670123456701234567" | |
183 ]; | |
184 | |
185 static const int[] test_repeat = [ | |
186 1, 1, 1, 1000000, 10 | |
187 ]; | |
188 | |
189 static const char[][] test_results = [ | |
190 "da39a3ee5e6b4b0d3255bfef95601890afd80709", | |
191 "a9993e364706816aba3e25717850c26c9cd0d89d", | |
192 "84983e441c3bd26ebaae4aa1f95129e5e54670f1", | |
193 "34aa973cd4c4daa4f61eeb2bdbad27316534016f", | |
194 "dea356a2cddd90c7a7ecedc5ebb563934f460452" | |
195 ]; | |
196 | |
197 SHA1 h = new SHA1(); | |
198 foreach (uint i, char[] input; test_inputs) { | |
199 for (int j = 0; j < test_repeat[i]; j++) | |
200 h.update(input); | |
201 char[] digest = h.hexDigest(); | |
202 assert(digest == test_results[i], | |
2
71aae178f89a
Added copy() to hash functions. Modified some code style.
Thomas Dixon <reikon@reikon.us>
parents:
0
diff
changeset
|
203 h.name~": ("~digest~") != ("~test_results[i]~")"); |
0 | 204 } |
205 } | |
206 } | |
207 } |