Mercurial > projects > dcrypt
comparison dcrypt/crypto/ciphers/AES.d @ 23:4589f8c5eb3c
Replaced dcrypt.crypto.Util with dcrypt.misc.Bitwise and dcrypt.misc.ByteConverter. Altered all dependent files to reflect changes.
author | Thomas Dixon <reikon@reikon.us> |
---|---|
date | Sat, 14 Feb 2009 19:58:20 -0500 |
parents | 5ce3012f1def |
children | 176c933827a8 |
comparison
equal
deleted
inserted
replaced
22:74303a717032 | 23:4589f8c5eb3c |
---|---|
6 * Authors: Thomas Dixon | 6 * Authors: Thomas Dixon |
7 */ | 7 */ |
8 | 8 |
9 module dcrypt.crypto.ciphers.AES; | 9 module dcrypt.crypto.ciphers.AES; |
10 | 10 |
11 import dcrypt.misc.Util; | 11 import dcrypt.misc.ByteConverter; |
12 import dcrypt.misc.Bitwise; | |
12 import dcrypt.crypto.BlockCipher; | 13 import dcrypt.crypto.BlockCipher; |
13 | 14 |
14 /** | 15 /** |
15 * Implementation of the US AES (Rijndael 128) cipher designed by | 16 * Implementation of the US AES (Rijndael 128) cipher designed by |
16 * Vincent Rijmen and Joan Daemen. | 17 * Vincent Rijmen and Joan Daemen. |
809 throw new ShortBufferError(name()~": Input buffer too short"); | 810 throw new ShortBufferError(name()~": Input buffer too short"); |
810 | 811 |
811 if (output.length < BLOCK_SIZE) | 812 if (output.length < BLOCK_SIZE) |
812 throw new ShortBufferError(name()~": Output buffer too short"); | 813 throw new ShortBufferError(name()~": Output buffer too short"); |
813 | 814 |
814 s0 = w[0] ^ Util.ubytesToUintBig(input, 0); | 815 s0 = w[0] ^ ByteConverter.BigEndian.to!(uint)(input[0..4]); |
815 s1 = w[1] ^ Util.ubytesToUintBig(input, 4); | 816 s1 = w[1] ^ ByteConverter.BigEndian.to!(uint)(input[4..8]); |
816 s2 = w[2] ^ Util.ubytesToUintBig(input, 8); | 817 s2 = w[2] ^ ByteConverter.BigEndian.to!(uint)(input[8..12]); |
817 s3 = w[3] ^ Util.ubytesToUintBig(input, 12); | 818 s3 = w[3] ^ ByteConverter.BigEndian.to!(uint)(input[12..16]); |
818 | 819 |
819 if (_encrypt) encryptBlock(); else decryptBlock(); | 820 (_encrypt) ? encryptBlock() : decryptBlock(); |
820 | 821 |
821 Util.uintToUbytesBig(s0, output, 0); | 822 output[0..4] = ByteConverter.BigEndian.from!(uint)(s0); |
822 Util.uintToUbytesBig(s1, output, 4); | 823 output[4..8] = ByteConverter.BigEndian.from!(uint)(s1); |
823 Util.uintToUbytesBig(s2, output, 8); | 824 output[8..12] = ByteConverter.BigEndian.from!(uint)(s2); |
824 Util.uintToUbytesBig(s3, output, 12); | 825 output[12..16] = ByteConverter.BigEndian.from!(uint)(s3); |
825 | 826 |
826 return BLOCK_SIZE; | 827 return BLOCK_SIZE; |
827 } | 828 } |
828 | 829 |
829 void reset() {} | 830 void reset() {} |
830 | 831 |
831 private uint subWord(uint x) { | 832 private uint subWord(uint x) { |
832 return ((S[x>>24] << 24) | | 833 return ((S[x>>24] << 24) | |
833 (S[cast(ubyte)(x>>8)] << 8) | | 834 (S[cast(ubyte)(x>>8)] << 8) | |
834 (S[cast(ubyte)(x>>16)] << 16)| | 835 (S[cast(ubyte)(x>>16)] << 16)| |
835 (S[cast(ubyte)x])); | 836 (S[cast(ubyte)x])); |
836 } | 837 } |
837 | 838 |
838 private void setup(ubyte[] key) { | 839 private void setup(ubyte[] key) { |
839 uint nk = key.length / 4; | 840 uint nk = key.length / 4; |
840 ROUNDS = nk + 6; | 841 ROUNDS = nk + 6; |
841 w = new uint[4*(ROUNDS+1)]; | 842 w = new uint[4*(ROUNDS+1)]; |
842 | 843 |
843 for (uint i = 0, j = 0; i < nk; i++, j+=4) | 844 for (uint i = 0, j = 0; i < nk; i++, j+=4) |
844 w[i] = Util.ubytesToUintBig(key, j); | 845 w[i] = ByteConverter.BigEndian.to!(uint)(key[j..j+int.sizeof]); |
845 | 846 |
846 for (uint i = nk; i < w.length; i++) { | 847 for (uint i = nk; i < w.length; i++) { |
847 uint t = w[i-1]; | 848 uint t = w[i-1]; |
848 | 849 |
849 if (i % nk == 0) | 850 if (i % nk == 0) |
850 t = subWord(Util.rotateLeft(t, 8)) ^ RCON[(i/nk)-1]; | 851 t = subWord(Bitwise.rotateLeft(t, 8)) ^ RCON[(i/nk)-1]; |
851 else if (nk > 6 && (i % nk == 4)) | 852 else if (nk > 6 && (i % nk == 4)) |
852 t = subWord(t); | 853 t = subWord(t); |
853 w[i] = w[i-nk] ^ t; | 854 w[i] = w[i-nk] ^ t; |
854 } | 855 } |
855 | 856 |
900 | 901 |
901 AES t = new AES(); | 902 AES t = new AES(); |
902 foreach (uint i, char[] test_key; test_keys) { | 903 foreach (uint i, char[] test_key; test_keys) { |
903 ubyte[] buffer = new ubyte[t.blockSize]; | 904 ubyte[] buffer = new ubyte[t.blockSize]; |
904 char[] result; | 905 char[] result; |
905 SymmetricKey key = new SymmetricKey(Util.hexToUbytes(test_key)); | 906 SymmetricKey key = new SymmetricKey(ByteConverter.hexDecode(test_key)); |
906 | 907 |
907 // Encryption | 908 // Encryption |
908 t.init(true, key); | 909 t.init(true, key); |
909 t.update(Util.hexToUbytes(test_plaintexts[i]), buffer); | 910 t.update(ByteConverter.hexDecode(test_plaintexts[i]), buffer); |
910 result = Util.ubytesToHex(buffer); | 911 result = ByteConverter.hexEncode(buffer); |
911 assert(result == test_ciphertexts[i], | 912 assert(result == test_ciphertexts[i], |
912 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); | 913 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); |
913 | 914 |
914 // Decryption | 915 // Decryption |
915 t.init(false, key); | 916 t.init(false, key); |
916 t.update(Util.hexToUbytes(test_ciphertexts[i]), buffer); | 917 t.update(ByteConverter.hexDecode(test_ciphertexts[i]), buffer); |
917 result = Util.ubytesToHex(buffer); | 918 result = ByteConverter.hexEncode(buffer); |
918 assert(result == test_plaintexts[i], | 919 assert(result == test_plaintexts[i], |
919 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); | 920 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); |
920 } | 921 } |
921 } | 922 } |
922 } | 923 } |