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