comparison dcrypt/crypto/hashes/SHA512.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
14 * Implementation of the US NSA's SHA-512. 14 * Implementation of the US NSA's SHA-512.
15 * 15 *
16 * Conforms: FIPS-180-2 16 * Conforms: FIPS-180-2
17 * References: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 17 * References: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
18 */ 18 */
19 class SHA512 : Hash { 19 class SHA512 : Hash
20 {
20 private const ulong[] K = [ 21 private const ulong[] K = [
21 0x428a2f98d728ae22u, 0x7137449123ef65cdu, 0xb5c0fbcfec4d3b2fu, 0xe9b5dba58189dbbcu, 22 0x428a2f98d728ae22u, 0x7137449123ef65cdu, 0xb5c0fbcfec4d3b2fu, 0xe9b5dba58189dbbcu,
22 0x3956c25bf348b538u, 0x59f111f1b605d019u, 0x923f82a4af194f9bu, 0xab1c5ed5da6d8118u, 23 0x3956c25bf348b538u, 0x59f111f1b605d019u, 0x923f82a4af194f9bu, 0xab1c5ed5da6d8118u,
23 0xd807aa98a3030242u, 0x12835b0145706fbeu, 0x243185be4ee4b28cu, 0x550c7dc3d5ffb4e2u, 24 0xd807aa98a3030242u, 0x12835b0145706fbeu, 0x243185be4ee4b28cu, 0x550c7dc3d5ffb4e2u,
24 0x72be5d74f27b896fu, 0x80deb1fe3b1696b1u, 0x9bdc06a725c71235u, 0xc19bf174cf692694u, 25 0x72be5d74f27b896fu, 0x80deb1fe3b1696b1u, 0x9bdc06a725c71235u, 0xc19bf174cf692694u,
37 0xca273eceea26619cu, 0xd186b8c721c0c207u, 0xeada7dd6cde0eb1eu, 0xf57d4f7fee6ed178u, 38 0xca273eceea26619cu, 0xd186b8c721c0c207u, 0xeada7dd6cde0eb1eu, 0xf57d4f7fee6ed178u,
38 0x06f067aa72176fbau, 0x0a637dc5a2c898a6u, 0x113f9804bef90daeu, 0x1b710b35131c471bu, 39 0x06f067aa72176fbau, 0x0a637dc5a2c898a6u, 0x113f9804bef90daeu, 0x1b710b35131c471bu,
39 0x28db77f523047d84u, 0x32caab7b40c72493u, 0x3c9ebe0a15c9bebcu, 0x431d67c49c100d4cu, 40 0x28db77f523047d84u, 0x32caab7b40c72493u, 0x3c9ebe0a15c9bebcu, 0x431d67c49c100d4cu,
40 0x4cc5d4becb3e42b6u, 0x597f299cfc657e2au, 0x5fcb6fab3ad6faecu, 0x6c44198c4a475817u 41 0x4cc5d4becb3e42b6u, 0x597f299cfc657e2au, 0x5fcb6fab3ad6faecu, 0x6c44198c4a475817u
41 ]; 42 ];
43
42 protected ulong h0, h1, h2, h3, h4, h5, h6, h7; 44 protected ulong h0, h1, h2, h3, h4, h5, h6, h7;
43 45
44 this (void[] input_=null) { 46 this (void[] input_=null)
47 {
45 reset(); 48 reset();
46 super(input_); 49 super(input_);
47 } 50 }
48 51
49 uint blockSize() { 52 uint blockSize()
53 {
50 return 128; 54 return 128;
51 } 55 }
52 56
53 uint digestSize() { 57 uint digestSize()
58 {
54 return 64; 59 return 64;
55 } 60 }
56 61
57 char[] name() { 62 char[] name()
63 {
58 return "SHA512"; 64 return "SHA512";
59 } 65 }
60 66
61 void transform(ubyte[] input) { 67 void transform(ubyte[] input)
68 {
62 ulong[] w = new ulong[80]; 69 ulong[] w = new ulong[80];
63 70
64 for (int i = 0, j = 0; i < 16; i++,j+=long.sizeof) 71 for (int i = 0, j = 0; i < 16; i++,j+=long.sizeof)
65 w[i] = ByteConverter.BigEndian.to!(ulong)(input[j..j+long.sizeof]); 72 w[i] = ByteConverter.BigEndian.to!(ulong)(input[j..j+long.sizeof]);
66 73
74 e = h4, 81 e = h4,
75 f = h5, 82 f = h5,
76 g = h6, 83 g = h6,
77 h = h7; 84 h = h7;
78 85
79 for (int i = 0; i < 80; i++) { 86 for (int i = 0; i < 80; i++)
87 {
80 ulong t1 = h + sum1(e) + ch(e,f,g) + K[i] + w[i], 88 ulong t1 = h + sum1(e) + ch(e,f,g) + K[i] + w[i],
81 t2 = sum0(a) + maj(a,b,c); 89 t2 = sum0(a) + maj(a,b,c);
82 h = g; 90 h = g;
83 g = f; 91 g = f;
84 f = e; 92 f = e;
97 h5 += f; 105 h5 += f;
98 h6 += g; 106 h6 += g;
99 h7 += h; 107 h7 += h;
100 } 108 }
101 109
102 private ulong ch(ulong x, ulong y, ulong z) { 110 private ulong ch(ulong x, ulong y, ulong z)
111 {
103 return (x&y)^(~x&z); 112 return (x&y)^(~x&z);
104 } 113 }
105 114
106 private ulong maj(ulong x, ulong y, ulong z) { 115 private ulong maj(ulong x, ulong y, ulong z)
116 {
107 return (x&y)^(x&z)^(y&z); 117 return (x&y)^(x&z)^(y&z);
108 } 118 }
109 119
110 private ulong sum0(ulong x) { 120 private ulong sum0(ulong x)
121 {
111 return (Bitwise.rotateRight(x,28)^ 122 return (Bitwise.rotateRight(x,28)^
112 Bitwise.rotateRight(x,34)^ 123 Bitwise.rotateRight(x,34)^
113 Bitwise.rotateRight(x,39)); 124 Bitwise.rotateRight(x,39));
114 } 125 }
115 126
116 private ulong sum1(ulong x) { 127 private ulong sum1(ulong x)
128 {
117 return (Bitwise.rotateRight(x,14)^ 129 return (Bitwise.rotateRight(x,14)^
118 Bitwise.rotateRight(x,18)^ 130 Bitwise.rotateRight(x,18)^
119 Bitwise.rotateRight(x,41)); 131 Bitwise.rotateRight(x,41));
120 } 132 }
121 133
122 private ulong theta0(ulong x) { 134 private ulong theta0(ulong x)
135 {
123 return Bitwise.rotateRight(x,1)^Bitwise.rotateRight(x,8)^(x >> 7); 136 return Bitwise.rotateRight(x,1)^Bitwise.rotateRight(x,8)^(x >> 7);
124 } 137 }
125 138
126 private ulong theta1(ulong x) { 139 private ulong theta1(ulong x)
140 {
127 return Bitwise.rotateRight(x,19)^Bitwise.rotateRight(x,61)^(x >> 6); 141 return Bitwise.rotateRight(x,19)^Bitwise.rotateRight(x,61)^(x >> 6);
128 } 142 }
129 143
130 ubyte[] digest() { 144 ubyte[] digest()
145 {
131 padMessage(MODE_SHA); 146 padMessage(MODE_SHA);
132 ubyte[] result = new ubyte[digestSize]; 147 ubyte[] result = new ubyte[digestSize];
133 148
134 result[0..8] = ByteConverter.BigEndian.from!(ulong)(h0); 149 result[0..8] = ByteConverter.BigEndian.from!(ulong)(h0);
135 result[8..16] = ByteConverter.BigEndian.from!(ulong)(h1); 150 result[8..16] = ByteConverter.BigEndian.from!(ulong)(h1);
142 157
143 reset(); 158 reset();
144 return result; 159 return result;
145 } 160 }
146 161
147 void reset() { 162 void reset()
163 {
148 super.reset(); 164 super.reset();
149 h0 = 0x6a09e667f3bcc908u; 165 h0 = 0x6a09e667f3bcc908u;
150 h1 = 0xbb67ae8584caa73bu; 166 h1 = 0xbb67ae8584caa73bu;
151 h2 = 0x3c6ef372fe94f82bu; 167 h2 = 0x3c6ef372fe94f82bu;
152 h3 = 0xa54ff53a5f1d36f1u; 168 h3 = 0xa54ff53a5f1d36f1u;
154 h5 = 0x9b05688c2b3e6c1fu; 170 h5 = 0x9b05688c2b3e6c1fu;
155 h6 = 0x1f83d9abfb41bd6bu; 171 h6 = 0x1f83d9abfb41bd6bu;
156 h7 = 0x5be0cd19137e2179u; 172 h7 = 0x5be0cd19137e2179u;
157 } 173 }
158 174
159 SHA512 copy() { 175 SHA512 copy()
176 {
160 SHA512 h = new SHA512(buffer[0..index]); 177 SHA512 h = new SHA512(buffer[0..index]);
161 h.bytes = bytes; 178 h.bytes = bytes;
162 h.h0 = h0; 179 h.h0 = h0;
163 h.h1 = h1; 180 h.h1 = h1;
164 h.h2 = h2; 181 h.h2 = h2;
168 h.h6 = h6; 185 h.h6 = h6;
169 h.h7 = h7; 186 h.h7 = h7;
170 return h; 187 return h;
171 } 188 }
172 189
173 debug (UnitTest) { 190 debug (UnitTest)
174 unittest { 191 {
192 unittest
193 {
175 static const char[][] test_inputs = [ 194 static const char[][] test_inputs = [
176 "", 195 "",
177 "abc", 196 "abc",
178 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"~ 197 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"~
179 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 198 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
197 "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"~ 216 "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"~
198 "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" 217 "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"
199 ]; 218 ];
200 219
201 SHA512 h = new SHA512(); 220 SHA512 h = new SHA512();
202 foreach (uint i, char[] input; test_inputs) { 221 foreach (uint i, char[] input; test_inputs)
222 {
203 for (int j = 0; j < test_repeat[i]; j++) 223 for (int j = 0; j < test_repeat[i]; j++)
204 h.update(input); 224 h.update(input);
205 char[] digest = h.hexDigest(); 225 char[] digest = h.hexDigest();
206 assert(digest == test_results[i], 226 assert(digest == test_results[i],
207 h.name~": ("~digest~") != ("~test_results[i]~")"); 227 h.name~": ("~digest~") != ("~test_results[i]~")");