changeset 26:176c933827a8

Implemented MD4. Refactored MD5. Replaced all instances of 'version (UnitTest)' with 'debug (UnitTest)'.
author Thomas Dixon <reikon@reikon.us>
date Sun, 01 Mar 2009 13:06:48 -0500
parents 528676d20398
children 8b5eaf3c2979
files dcrypt/crypto/ciphers/AES.d dcrypt/crypto/ciphers/Blowfish.d dcrypt/crypto/ciphers/ChaCha.d dcrypt/crypto/ciphers/RC4.d dcrypt/crypto/ciphers/RC6.d dcrypt/crypto/ciphers/Salsa20.d dcrypt/crypto/ciphers/XTEA.d dcrypt/crypto/hashes/MD4.d dcrypt/crypto/hashes/MD5.d dcrypt/crypto/hashes/SHA1.d dcrypt/crypto/hashes/SHA224.d dcrypt/crypto/hashes/SHA256.d dcrypt/crypto/hashes/SHA384.d dcrypt/crypto/hashes/SHA512.d dcrypt/crypto/macs/HMAC.d dcrypt/crypto/modes/CBC.d dcrypt/crypto/prngs/PBKDF2.d dcrypt/misc/checksums/Adler32.d dcrypt/misc/checksums/CRC32.d
diffstat 19 files changed, 314 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/dcrypt/crypto/ciphers/AES.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/AES.d	Sun Mar 01 13:06:48 2009 -0500
@@ -851,6 +851,7 @@
                 t = subWord(Bitwise.rotateLeft(t, 8)) ^ RCON[(i/nk)-1];
             else if (nk > 6 && (i % nk == 4))
                 t = subWord(t);
+                
             w[i] = w[i-nk] ^ t;
         }
         
@@ -869,7 +870,7 @@
     }
     
     /** Some AES test vectors from the FIPS-197 paper and BC. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "000102030405060708090a0b0c0d0e0f",
--- a/dcrypt/crypto/ciphers/Blowfish.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/Blowfish.d	Sun Mar 01 13:06:48 2009 -0500
@@ -336,7 +336,7 @@
     }
     
     /** Some Blowfish test vectors from Schneier's site. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "0000000000000000",
--- a/dcrypt/crypto/ciphers/ChaCha.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/ChaCha.d	Sun Mar 01 13:06:48 2009 -0500
@@ -105,7 +105,7 @@
     }
     
     /** ChaCha test vectors */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "80000000000000000000000000000000", 
--- a/dcrypt/crypto/ciphers/RC4.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/RC4.d	Sun Mar 01 13:06:48 2009 -0500
@@ -10,7 +10,7 @@
 
 import dcrypt.crypto.StreamCipher;
 
-version (UnitTest) {
+debug (UnitTest) {
     import dcrypt.misc.ByteConverter;
 }
 
@@ -101,7 +101,7 @@
     }
     
     /** Some RC4 test vectors. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "0123456789abcdef",
--- a/dcrypt/crypto/ciphers/RC6.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/RC6.d	Sun Mar 01 13:06:48 2009 -0500
@@ -150,7 +150,7 @@
     }
     
     /** Some RC6 test vectors from the spec. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "00000000000000000000000000000000",
--- a/dcrypt/crypto/ciphers/Salsa20.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/Salsa20.d	Sun Mar 01 13:06:48 2009 -0500
@@ -215,7 +215,7 @@
     }
     
     /** Salsa20 test vectors */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "80000000000000000000000000000000", 
--- a/dcrypt/crypto/ciphers/XTEA.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/ciphers/XTEA.d	Sun Mar 01 13:06:48 2009 -0500
@@ -97,7 +97,7 @@
     }
     
     /** Some XTEA test vectors. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "00000000000000000000000000000000",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dcrypt/crypto/hashes/MD4.d	Sun Mar 01 13:06:48 2009 -0500
@@ -0,0 +1,219 @@
+/**
+ * This file is part of the dcrypt project.
+ *
+ * Copyright: Copyright (C) dcrypt contributors 2009. All rights reserved.
+ * License:   MIT
+ * Authors:   Thomas Dixon
+ */
+
+module dcrypt.crypto.hashes.MD4;
+
+public import dcrypt.crypto.Hash;
+
+/** 
+ * Implementation of Ron Rivest's MD4.
+ * 
+ * Conforms: RFC 1320
+ * References: http://www.faqs.org/rfcs/rfc1320.html
+ * Bugs: MD4 is not cryptographically secure.
+ */
+class MD4 : Hash {
+	private uint h0, h1, h2, h3;
+    
+    // Shift amounts
+    private enum {
+        S11 =  3,
+        S12 =  7,
+        S13 = 11,
+        S14 = 19,
+        
+        S21 =  3,
+        S22 =  5,
+        S23 =  9,
+        S24 = 13,
+        
+        S31 =  3,
+        S32 =  9,
+        S33 = 11,
+        S34 = 15
+    };
+    
+    this (void[] input_=null) {
+        reset();
+        super(input_);
+    }
+
+    uint blockSize() {
+        return 64;
+    }
+    
+    uint digestSize() {
+        return 16;
+    }
+    
+    char[] name() {
+        return "MD4";
+    }
+    
+    void transform(ubyte[] input) {
+        uint[] w = new uint[16];
+        
+        for (int i = 0, j = 0; i < 16; i++,j+=int.sizeof)
+            w[i] = ByteConverter.LittleEndian.to!(uint)(input[j..j+int.sizeof]);
+        
+        uint a = h0,
+             b = h1,
+             c = h2,
+             d = h3;
+        
+        // Round 1
+        ff(a, b, c, d, w[ 0], S11);
+        ff(d, a, b, c, w[ 1], S12);
+        ff(c, d, a, b, w[ 2], S13);
+        ff(b, c, d, a, w[ 3], S14);
+        ff(a, b, c, d, w[ 4], S11);
+        ff(d, a, b, c, w[ 5], S12);
+        ff(c, d, a, b, w[ 6], S13);
+        ff(b, c, d, a, w[ 7], S14);
+        ff(a, b, c, d, w[ 8], S11);
+        ff(d, a, b, c, w[ 9], S12);
+        ff(c, d, a, b, w[10], S13);
+        ff(b, c, d, a, w[11], S14);
+        ff(a, b, c, d, w[12], S11);
+        ff(d, a, b, c, w[13], S12);
+        ff(c, d, a, b, w[14], S13);
+        ff(b, c, d, a, w[15], S14);
+        
+        // Round 2
+        gg(a, b, c, d, w[ 0], S21);
+        gg(d, a, b, c, w[ 4], S22);
+        gg(c, d, a, b, w[ 8], S23);
+        gg(b, c, d, a, w[12], S24);
+        gg(a, b, c, d, w[ 1], S21);
+        gg(d, a, b, c, w[ 5], S22);
+        gg(c, d, a, b, w[ 9], S23);
+        gg(b, c, d, a, w[13], S24);
+        gg(a, b, c, d, w[ 2], S21);
+        gg(d, a, b, c, w[ 6], S22);
+        gg(c, d, a, b, w[10], S23);
+        gg(b, c, d, a, w[14], S24);
+        gg(a, b, c, d, w[ 3], S21);
+        gg(d, a, b, c, w[ 7], S22);
+        gg(c, d, a, b, w[11], S23);
+        gg(b, c, d, a, w[15], S24);
+        
+        // Round 3
+        hh(a, b, c, d, w[ 0], S31);
+        hh(d, a, b, c, w[ 8], S32);
+        hh(c, d, a, b, w[ 4], S33);
+        hh(b, c, d, a, w[12], S34);
+        hh(a, b, c, d, w[ 2], S31);
+        hh(d, a, b, c, w[10], S32);
+        hh(c, d, a, b, w[ 6], S33);
+        hh(b, c, d, a, w[14], S34);
+        hh(a, b, c, d, w[ 1], S31);
+        hh(d, a, b, c, w[ 9], S32);
+        hh(c, d, a, b, w[ 5], S33);
+        hh(b, c, d, a, w[13], S34);
+        hh(a, b, c, d, w[ 3], S31);
+        hh(d, a, b, c, w[11], S32);
+        hh(c, d, a, b, w[ 7], S33);
+        hh(b, c, d, a, w[15], S34);
+          
+        h0 += a;
+        h1 += b;
+        h2 += c;
+        h3 += d;
+    }
+    
+    private uint f(uint x, uint y, uint z) {
+        return (x&y)|(~x&z);
+    }
+
+    private uint h(uint x, uint y, uint z) {
+        return x^y^z;
+    }
+    
+    private uint g(uint x, uint y, uint z) {
+        return (x&y)|(x&z)|(y&z);
+    }
+
+    private void ff(ref uint a, uint b, uint c, uint d, uint x, uint s) {
+        a += f(b, c, d) + x;
+        a = Bitwise.rotateLeft(a, s);
+    }
+
+    private void gg(ref uint a, uint b, uint c, uint d, uint x, uint s) {
+        a += g(b, c, d) + x + 0x5a827999u;
+        a = Bitwise.rotateLeft(a, s);
+    }
+
+    private void hh(ref uint a, uint b, uint c, uint d, uint x, uint s) {
+        a += h(b, c, d) + x + 0x6ed9eba1u;
+        a = Bitwise.rotateLeft(a, s);
+    }
+
+    ubyte[] digest() {
+    	padMessage(MODE_MD);
+        ubyte[] result = new ubyte[digestSize];
+        
+        result[0..4] = ByteConverter.LittleEndian.from!(uint)(h0);
+        result[4..8] = ByteConverter.LittleEndian.from!(uint)(h1);
+        result[8..12] = ByteConverter.LittleEndian.from!(uint)(h2);
+        result[12..16] = ByteConverter.LittleEndian.from!(uint)(h3);
+        
+        reset();
+        return result;
+    }
+
+    void reset() {
+        super.reset();
+        h0 = 0x67452301u;
+        h1 = 0xefcdab89u;
+        h2 = 0x98badcfeu;
+        h3 = 0x10325476u;
+    }
+    
+    MD4 copy() {
+        MD4 h = new MD4(buffer[0..index]);
+        h.bytes = bytes;
+        h.h0 = h0;
+        h.h1 = h1;
+        h.h2 = h2;
+        h.h3 = h3;
+        return h;
+    }
+    
+    debug (UnitTest) {
+        // Found in Tango <3
+        unittest {
+            static const char[][] test_inputs = [
+                "",
+                "a",
+                "abc",
+                "message digest",
+                "abcdefghijklmnopqrstuvwxyz",
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+                "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+            ];
+            
+            static const char[][] test_results = [
+                "31d6cfe0d16ae931b73c59d7e0c089c0",
+                "bde52cb31de33e46245e05fbdbd6fb24",
+                "a448017aaf21d8525fc10ae87aa6729d",
+                "d9130a8164549fe818874806e1c7014b",
+                "d79e1c308aa5bbcdeea8ed63df412da9",
+                "043f8582f241db351ce627e153e7f0e4",
+                "e33b4ddc9c38f2199c3e7b164fcc0536"
+            ];
+            
+            MD4 h = new MD4();
+            foreach (uint i, char[] input; test_inputs) {
+                h.update(input);
+                char[] digest = h.hexDigest();
+                assert(digest == test_results[i], 
+                        h.name~": ("~digest~") != ("~test_results[i]~")");
+            }
+        }
+    }
+}
--- a/dcrypt/crypto/hashes/MD5.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/MD5.d	Sun Mar 01 13:06:48 2009 -0500
@@ -16,7 +16,6 @@
  * Conforms: RFC 1321
  * References: http://www.faqs.org/rfcs/rfc1321.html
  * Bugs: MD5 is not cryptographically secure.
- * Throws: InsecureAlgorithmError upon instantiation.
  */
 class MD5 : Hash {
 	private uint h0, h1, h2, h3;
@@ -73,91 +72,91 @@
              d = h3;
         
         // Round 1 -- FIGHT!
-        ff(a, b, c, d, w[ 0], S11, 3614090360); /* 1 */
-        ff(d, a, b, c, w[ 1], S12, 3905402710); /* 2 */
-        ff(c, d, a, b, w[ 2], S13,  606105819); /* 3 */
-        ff(b, c, d, a, w[ 3], S14, 3250441966); /* 4 */
-        ff(a, b, c, d, w[ 4], S11, 4118548399); /* 5 */
-        ff(d, a, b, c, w[ 5], S12, 1200080426); /* 6 */
-        ff(c, d, a, b, w[ 6], S13, 2821735955); /* 7 */
-        ff(b, c, d, a, w[ 7], S14, 4249261313); /* 8 */
-        ff(a, b, c, d, w[ 8], S11, 1770035416); /* 9 */
-        ff(d, a, b, c, w[ 9], S12, 2336552879); /* 10 */
-        ff(c, d, a, b, w[10], S13, 4294925233); /* 11 */
-        ff(b, c, d, a, w[11], S14, 2304563134); /* 12 */
-        ff(a, b, c, d, w[12], S11, 1804603682); /* 13 */
-        ff(d, a, b, c, w[13], S12, 4254626195); /* 14 */
-        ff(c, d, a, b, w[14], S13, 2792965006); /* 15 */
-        ff(b, c, d, a, w[15], S14, 1236535329); /* 16 */
-        
+        ff(a, b, c, d, w[ 0], S11, 0xd76aa478u);
+        ff(d, a, b, c, w[ 1], S12, 0xe8c7b756u);
+        ff(c, d, a, b, w[ 2], S13, 0x242070dbu);
+        ff(b, c, d, a, w[ 3], S14, 0xc1bdceeeu);
+        ff(a, b, c, d, w[ 4], S11, 0xf57c0fafu);
+        ff(d, a, b, c, w[ 5], S12, 0x4787c62au);
+        ff(c, d, a, b, w[ 6], S13, 0xa8304613u);
+        ff(b, c, d, a, w[ 7], S14, 0xfd469501u);
+        ff(a, b, c, d, w[ 8], S11, 0x698098d8u);
+        ff(d, a, b, c, w[ 9], S12, 0x8b44f7afu);
+        ff(c, d, a, b, w[10], S13, 0xffff5bb1u);
+        ff(b, c, d, a, w[11], S14, 0x895cd7beu);
+        ff(a, b, c, d, w[12], S11, 0x6b901122u);
+        ff(d, a, b, c, w[13], S12, 0xfd987193u);
+        ff(c, d, a, b, w[14], S13, 0xa679438eu);
+        ff(b, c, d, a, w[15], S14, 0x49b40821u);
+
         // Round 2
-        gg(a, b, c, d, w[ 1], S21, 4129170786); /* 17 */
-        gg(d, a, b, c, w[ 6], S22, 3225465664); /* 18 */
-        gg(c, d, a, b, w[11], S23,  643717713); /* 19 */
-        gg(b, c, d, a, w[ 0], S24, 3921069994); /* 20 */
-        gg(a, b, c, d, w[ 5], S21, 3593408605); /* 21 */
-        gg(d, a, b, c, w[10], S22,   38016083); /* 22 */
-        gg(c, d, a, b, w[15], S23, 3634488961); /* 23 */
-        gg(b, c, d, a, w[ 4], S24, 3889429448); /* 24 */
-        gg(a, b, c, d, w[ 9], S21,  568446438); /* 25 */
-        gg(d, a, b, c, w[14], S22, 3275163606); /* 26 */
-        gg(c, d, a, b, w[ 3], S23, 4107603335); /* 27 */
-        gg(b, c, d, a, w[ 8], S24, 1163531501); /* 28 */
-        gg(a, b, c, d, w[13], S21, 2850285829); /* 29 */
-        gg(d, a, b, c, w[ 2], S22, 4243563512); /* 30 */
-        gg(c, d, a, b, w[ 7], S23, 1735328473); /* 31 */
-        gg(b, c, d, a, w[12], S24, 2368359562); /* 32 */
-        
+        gg(a, b, c, d, w[ 1], S21, 0xf61e2562u);
+        gg(d, a, b, c, w[ 6], S22, 0xc040b340u);
+        gg(c, d, a, b, w[11], S23, 0x265e5a51u);
+        gg(b, c, d, a, w[ 0], S24, 0xe9b6c7aau);
+        gg(a, b, c, d, w[ 5], S21, 0xd62f105du);
+        gg(d, a, b, c, w[10], S22, 0x02441453u);
+        gg(c, d, a, b, w[15], S23, 0xd8a1e681u);
+        gg(b, c, d, a, w[ 4], S24, 0xe7d3fbc8u);
+        gg(a, b, c, d, w[ 9], S21, 0x21e1cde6u);
+        gg(d, a, b, c, w[14], S22, 0xc33707d6u);
+        gg(c, d, a, b, w[ 3], S23, 0xf4d50d87u);
+        gg(b, c, d, a, w[ 8], S24, 0x455a14edu);
+        gg(a, b, c, d, w[13], S21, 0xa9e3e905u);
+        gg(d, a, b, c, w[ 2], S22, 0xfcefa3f8u);
+        gg(c, d, a, b, w[ 7], S23, 0x676f02d9u);
+        gg(b, c, d, a, w[12], S24, 0x8d2a4c8au);
+
         // Round 3
-        hh(a, b, c, d, w[ 5], S31, 4294588738); /* 33 */
-        hh(d, a, b, c, w[ 8], S32, 2272392833); /* 34 */
-        hh(c, d, a, b, w[11], S33, 1839030562); /* 35 */
-        hh(b, c, d, a, w[14], S34, 4259657740); /* 36 */
-        hh(a, b, c, d, w[ 1], S31, 2763975236); /* 37 */
-        hh(d, a, b, c, w[ 4], S32, 1272893353); /* 38 */
-        hh(c, d, a, b, w[ 7], S33, 4139469664); /* 39 */
-        hh(b, c, d, a, w[10], S34, 3200236656); /* 40 */
-        hh(a, b, c, d, w[13], S31,  681279174); /* 41 */
-        hh(d, a, b, c, w[ 0], S32, 3936430074); /* 42 */
-        hh(c, d, a, b, w[ 3], S33, 3572445317); /* 43 */
-        hh(b, c, d, a, w[ 6], S34,   76029189); /* 44 */
-        hh(a, b, c, d, w[ 9], S31, 3654602809); /* 45 */
-        hh(d, a, b, c, w[12], S32, 3873151461); /* 46 */
-        hh(c, d, a, b, w[15], S33,  530742520); /* 47 */
-        hh(b, c, d, a, w[ 2], S34, 3299628645); /* 48 */
-        
+        hh(a, b, c, d, w[ 5], S31, 0xfffa3942u);
+        hh(d, a, b, c, w[ 8], S32, 0x8771f681u);
+        hh(c, d, a, b, w[11], S33, 0x6d9d6122u);
+        hh(b, c, d, a, w[14], S34, 0xfde5380cu);
+        hh(a, b, c, d, w[ 1], S31, 0xa4beea44u);
+        hh(d, a, b, c, w[ 4], S32, 0x4bdecfa9u);
+        hh(c, d, a, b, w[ 7], S33, 0xf6bb4b60u);
+        hh(b, c, d, a, w[10], S34, 0xbebfbc70u);
+        hh(a, b, c, d, w[13], S31, 0x289b7ec6u);
+        hh(d, a, b, c, w[ 0], S32, 0xeaa127fau);
+        hh(c, d, a, b, w[ 3], S33, 0xd4ef3085u);
+        hh(b, c, d, a, w[ 6], S34, 0x04881d05u);
+        hh(a, b, c, d, w[ 9], S31, 0xd9d4d039u);
+        hh(d, a, b, c, w[12], S32, 0xe6db99e5u);
+        hh(c, d, a, b, w[15], S33, 0x1fa27cf8u);
+        hh(b, c, d, a, w[ 2], S34, 0xc4ac5665u);
+
         // Round 4
-        ii(a, b, c, d, w[ 0], S41, 4096336452); /* 49 */
-        ii(d, a, b, c, w[ 7], S42, 1126891415); /* 50 */
-        ii(c, d, a, b, w[14], S43, 2878612391); /* 51 */
-        ii(b, c, d, a, w[ 5], S44, 4237533241); /* 52 */
-        ii(a, b, c, d, w[12], S41, 1700485571); /* 53 */
-        ii(d, a, b, c, w[ 3], S42, 2399980690); /* 54 */
-        ii(c, d, a, b, w[10], S43, 4293915773); /* 55 */
-        ii(b, c, d, a, w[ 1], S44, 2240044497); /* 56 */
-        ii(a, b, c, d, w[ 8], S41, 1873313359); /* 57 */
-        ii(d, a, b, c, w[15], S42, 4264355552); /* 58 */
-        ii(c, d, a, b, w[ 6], S43, 2734768916); /* 59 */
-        ii(b, c, d, a, w[13], S44, 1309151649); /* 60 */
-        ii(a, b, c, d, w[ 4], S41, 4149444226); /* 61 */
-        ii(d, a, b, c, w[11], S42, 3174756917); /* 62 */
-        ii(c, d, a, b, w[ 2], S43,  718787259); /* 63 */
-        ii(b, c, d, a, w[ 9], S44, 3951481745); /* 64 */
+        ii(a, b, c, d, w[ 0], S41, 0xf4292244u);
+        ii(d, a, b, c, w[ 7], S42, 0x432aff97u);
+        ii(c, d, a, b, w[14], S43, 0xab9423a7u);
+        ii(b, c, d, a, w[ 5], S44, 0xfc93a039u);
+        ii(a, b, c, d, w[12], S41, 0x655b59c3u);
+        ii(d, a, b, c, w[ 3], S42, 0x8f0ccc92u);
+        ii(c, d, a, b, w[10], S43, 0xffeff47du);
+        ii(b, c, d, a, w[ 1], S44, 0x85845dd1u);
+        ii(a, b, c, d, w[ 8], S41, 0x6fa87e4fu);
+        ii(d, a, b, c, w[15], S42, 0xfe2ce6e0u);
+        ii(c, d, a, b, w[ 6], S43, 0xa3014314u);
+        ii(b, c, d, a, w[13], S44, 0x4e0811a1u);
+        ii(a, b, c, d, w[ 4], S41, 0xf7537e82u);
+        ii(d, a, b, c, w[11], S42, 0xbd3af235u);
+        ii(c, d, a, b, w[ 2], S43, 0x2ad7d2bbu);
+        ii(b, c, d, a, w[ 9], S44, 0xeb86d391u);   
         
         // FINISH HIM!
         h0 += a;
         h1 += b;
         h2 += c;
         h3 += d;
-        // FATALITY! MD5 Wins. \o/ ('cept not because it's insecure, but whatev)
+        // FATALITY! \o/
     }
     
     private uint f(uint x, uint y, uint z) {
-            return (x&y)|(~x&z);
+        return (x&y)|(~x&z);
     }
 
     private uint h(uint x, uint y, uint z) {
-            return x^y^z;
+        return x^y^z;
     }
     
     private uint g(uint x, uint y, uint z) {
@@ -211,9 +210,9 @@
 
     void reset() {
         super.reset();
-        h0 = 0x67452301u,
-        h1 = 0xefcdab89u,
-        h2 = 0x98badcfeu,
+        h0 = 0x67452301u;
+        h1 = 0xefcdab89u;
+        h2 = 0x98badcfeu;
         h3 = 0x10325476u;
     }
     
@@ -227,7 +226,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         // Found in Tango <3
         unittest {
             static const char[][] test_inputs = [
--- a/dcrypt/crypto/hashes/SHA1.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/SHA1.d	Sun Mar 01 13:06:48 2009 -0500
@@ -178,7 +178,7 @@
         return h;
     }
    
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_inputs = [
                 "",
--- a/dcrypt/crypto/hashes/SHA224.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/SHA224.d	Sun Mar 01 13:06:48 2009 -0500
@@ -73,7 +73,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_inputs = [
                 "",
--- a/dcrypt/crypto/hashes/SHA256.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/SHA256.d	Sun Mar 01 13:06:48 2009 -0500
@@ -162,7 +162,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_inputs = [
                 "",
--- a/dcrypt/crypto/hashes/SHA384.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/SHA384.d	Sun Mar 01 13:06:48 2009 -0500
@@ -71,7 +71,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_inputs = [
                 "",
--- a/dcrypt/crypto/hashes/SHA512.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/hashes/SHA512.d	Sun Mar 01 13:06:48 2009 -0500
@@ -170,7 +170,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_inputs = [
                 "",
--- a/dcrypt/crypto/macs/HMAC.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/macs/HMAC.d	Sun Mar 01 13:06:48 2009 -0500
@@ -13,7 +13,7 @@
 import dcrypt.crypto.params.SymmetricKey;
 import dcrypt.crypto.errors.NotInitializedError;
 
-version (UnitTest) {
+debug (UnitTest) {
     import dcrypt.crypto.hashes.SHA1;
 }
 
@@ -113,7 +113,7 @@
         return h;
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static char[][] test_keys = [
                 "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
--- a/dcrypt/crypto/modes/CBC.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/modes/CBC.d	Sun Mar 01 13:06:48 2009 -0500
@@ -11,7 +11,7 @@
 import dcrypt.crypto.BlockCipher;
 public import dcrypt.crypto.params.ParametersWithIV;
 
-version (UnitTest) {
+debug (UnitTest) {
     import dcrypt.crypto.ciphers.XTEA;
     import dcrypt.misc.ByteConverter;
 }
@@ -122,7 +122,7 @@
     }
     
     /** Test vectors for CBC mode. Assumes XTEA passes test vectors. */
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static const char[][] test_keys = [
                 "00000000000000000000000000000000",            
--- a/dcrypt/crypto/prngs/PBKDF2.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/crypto/prngs/PBKDF2.d	Sun Mar 01 13:06:48 2009 -0500
@@ -105,7 +105,7 @@
         return "PBKDF2-"~prf.name;
     }
 
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static char[][] test_passwords = [
                 "password",
--- a/dcrypt/misc/checksums/Adler32.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/misc/checksums/Adler32.d	Sun Mar 01 13:06:48 2009 -0500
@@ -37,7 +37,7 @@
         return "Adler32";
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static char[][] test_inputs = [
                 "",
--- a/dcrypt/misc/checksums/CRC32.d	Thu Feb 19 19:35:43 2009 -0500
+++ b/dcrypt/misc/checksums/CRC32.d	Sun Mar 01 13:06:48 2009 -0500
@@ -81,7 +81,7 @@
         return "CRC32";
     }
     
-    version (UnitTest) {
+    debug (UnitTest) {
         unittest {
             static char[][] test_inputs = [
                 "",