Advertisement
Guest User

Challenge7

a guest
Dec 2nd, 2015
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.92 KB | None | 0 0
  1. package cryptopals.set1;
  2.  
  3. import static cryptopals.set1.Challenge7.Message.transpose;
  4. import java.util.Arrays;
  5.  
  6. public class Challenge7 {
  7.  
  8.     private static final int ksize = 128;
  9.     private static final int rounds = 10;
  10.  
  11. //    public static void main(String[] args) throws Exception{
  12. //        byte[] message = DatatypeConverter.parseBase64Binary(Challenge7.encoded);
  13. //        byte[] key = "YELLOW SUBMARINE".getBytes();
  14. //        Message m = new Message(message);
  15. //        m.decrypt(key, Mode.ECB);
  16. //        System.out.println(new String(m.getData()));
  17. //    }
  18.    
  19.     public static void print(byte[] arr) {
  20.         for(int i = 0; i < 16; i++) {
  21.             if(i % 4 == 0 && i != 0) {
  22.                 System.out.println();
  23.             }
  24.             System.out.print(Integer.toHexString(arr[i] & 0xFF) + " ");
  25.         }
  26.         System.out.println();
  27.     }
  28.  
  29.     public static byte[][] expandKey(byte[] key, byte[] sbox) {
  30.         byte[][] expanded = new byte[rounds + 1][ksize / 8];
  31.         expanded[0] = key;
  32.         byte[] lastKey = copy(key);
  33.         for(int i = 1; i <= 10; i++) {
  34.             for(int wordID = 0; wordID < 4; wordID++) {
  35.                 if(wordID == 0) {
  36.                     byte[] word = getWord(lastKey, 3);
  37.                     rotWord(word);
  38.                     subBytes(word, sbox);
  39.                     xor(word, getWord(lastKey, 0));
  40.                     xor(word, rcon[i - 1]);
  41.                     setWord(lastKey, word, 0);
  42.                 }
  43.                 else {
  44.                     byte[] word = getWord(lastKey, wordID);
  45.                     xor(word, getWord(lastKey, wordID - 1));
  46.                     setWord(lastKey, word, wordID);
  47.                 }
  48.             }
  49.             expanded[i] = copy(lastKey);
  50.         }
  51.         return expanded;
  52.     }
  53.  
  54.     public static void xor(byte[] arr1, byte[] arr2) {
  55.         for(int i = 0; i < arr1.length; i++) {
  56.             arr1[i] ^= arr2[i];
  57.         }
  58.     }
  59.  
  60.     public static byte[] getWord(byte[] block, int wordID) {
  61.         byte[] word = new byte[block.length / 4];
  62.         for(int i = wordID; i < block.length; i += 4) {
  63.             byte b = block[i];
  64.             word[i / 4] = b;
  65.         }
  66.         return word;
  67.     }
  68.  
  69.     public static void setWord(byte[] block, byte[] word, int wordID) {
  70.         for(int i = 0; i < word.length; i++) {
  71.             byte b = word[i];
  72.             block[4 * i + wordID] = b;
  73.         }
  74.     }
  75.  
  76.     private static byte[] copy(byte[] bytes) {
  77.         byte[] copy = new byte[bytes.length];
  78.         System.arraycopy(bytes, 0, copy, 0, bytes.length);
  79.         return copy;
  80.     }
  81.  
  82.     private static void rotWord(byte[] word) {
  83.         byte temp = word[0];
  84.         word[0] = word[1];
  85.         word[1] = word[2];
  86.         word[2] = word[3];
  87.         word[3] = temp;
  88.     }
  89.  
  90.     private static void subBytes(byte[] word, byte[] sbox) {
  91.         for(int i = 0; i < word.length; i++) {
  92.             byte b = word[i];
  93.             word[i] = (byte)sbox[(((b >> 4) * 0x10) + (b & 0xf)) & 0xFF];
  94.         }
  95.     }
  96.    
  97.     public static enum Mode {
  98.         ECB,
  99.         CBC;
  100.     }
  101.    
  102.     public static class Message {
  103.        
  104.         private final Block[] blocks;
  105.        
  106.         public Message(byte[] bytes) {
  107.             blocks = new Block[(int)Math.ceil(bytes.length / 16.0)];
  108.             for(int i = 0; i < blocks.length; i++) {
  109.                 byte[] data = new byte[16];
  110.                 Arrays.fill(data, (byte)0);
  111.                 for(int j = 0; j < 16 && i * 16 + j < bytes.length; j++) {
  112.                     data[j] = bytes[i * 16 + j];
  113.                 }
  114.                 blocks[i] = new Block(transpose(data));
  115.             }
  116.         }
  117.        
  118.         public static byte[] transpose(byte[] c) {
  119.             byte[] t = new byte[c.length];
  120.             int cid = 0;
  121.             for(int i = 0; i != 16; i = (i > 0xB) ? i != 15 ? (i + 12) % 23 : 16 : i + 4) {
  122.                 t[i] = c[cid++];
  123.             }
  124.             return t;
  125.         }
  126.        
  127.         public void encrypt(byte[] key, Mode mode) {
  128.             encrypt(key, null, mode);
  129.         }
  130.        
  131.         public void decrypt(byte[] key, Mode mode) {
  132.             decrypt(key, null, mode);
  133.         }
  134.        
  135.         public void encrypt(byte[] key, byte[] iv, Mode mode) {
  136.             byte[][] expanded = expandKey(transpose(key), s);
  137.             for(Block block : blocks) {
  138.                 if(mode == Mode.ECB) {  
  139.                     block.encrypt(expanded);
  140.                 }
  141.                 else if(mode == Mode.CBC) {
  142.                     block.xorData(iv);
  143.                     block.encrypt(expanded);
  144.                     iv = block.getData();
  145.                 }
  146.             }
  147.         }
  148.        
  149.         public void decrypt(byte[] key, byte[] iv, Mode mode) {
  150.             byte[][] expanded = expandKey(transpose(key), s);
  151.             for(Block block : blocks) {
  152.                 if(mode == Mode.ECB) {  
  153.                     block.decrypt(expanded);
  154.                 }
  155.                 else if(mode == Mode.CBC) {
  156.                     byte[] temp = copy(iv);
  157.                     iv = copy(block.getData());
  158.                     block.decrypt(expanded);
  159.                     block.xorData(temp);
  160.                 }
  161.             }
  162.         }
  163.        
  164.         public byte[] getData() {
  165.             byte[] bytes = new byte[blocks.length * 16];
  166.             for(int i = 0; i < blocks.length; i++) {
  167.                 Block block = blocks[i];
  168.                 System.arraycopy(transpose(block.getData()), 0, bytes, i * 16, 16);
  169.             }
  170.             return bytes;
  171.         }
  172.     }
  173.  
  174.     public static class Block {
  175.  
  176.         private final byte[] block;
  177.  
  178.         public Block(byte[] block) {
  179.             this.block = block;
  180.         }
  181.        
  182.         public byte[] getData() {
  183.             return block;
  184.         }
  185.        
  186.         public void xorData(byte[] xor) {
  187.             xor(block, transpose(xor));
  188.         }
  189.  
  190.         private void encrypt(byte[][] expanded) {
  191.             xor(block, expanded[0]);
  192.             for(int i = 1; i < expanded.length; i++) {
  193.                 subBytes(block, s);
  194.                 shiftRows(block);
  195.                 if(i < expanded.length - 1) {
  196.                     mixColumns(mix);
  197.                 }
  198.                 xor(block, expanded[i]);
  199.             }
  200.         }
  201.        
  202.         private void decrypt(byte[][] expanded) {
  203.             xor(block, expanded[expanded.length - 1]);
  204.             shiftRowsBack(block);
  205.             subBytes(block, inv_s);
  206.             for(int i = 9; i >= 0; i--) {
  207.                 xor(block, expanded[i]);
  208.                 if(i > 0) {  
  209.                     mixColumns(inv_mix);
  210.                     shiftRowsBack(block);
  211.                     subBytes(block, inv_s);
  212.                 }
  213.             }
  214.         }
  215.  
  216.         private void mixColumns(byte[][] mix) {
  217.             for(int i = 0; i < block.length / 4; i++) {
  218.                 byte[] word = getWord(block, i);
  219.                 byte[] mixed = copy(word);
  220.                 for(int j = 0; j < word.length; j++) {
  221.                     mixed[j] = (byte)((m(word[0], mix[j][0]) ^ m(word[1], mix[j][1]) ^ m(word[2], mix[j][2]) ^ m(word[3], mix[j][3])) % 0xFF);
  222.                 }
  223.                 setWord(block, mixed, i);
  224.             }
  225.         }
  226.  
  227.         private byte m(int c, int m) {
  228.             c &= 0xFF;
  229.             switch(m) {
  230.                 case 0x01: {
  231.                     return (byte)c;
  232.                 }
  233.                 case 0x02: {
  234.                     int r = (c << 1);
  235.                     if(c >= 0x80) {
  236.                         r ^= 0x1b;
  237.                     }
  238.                     return (byte)(r % 0x100);
  239.                 }
  240.                 case 0x03: {
  241.                     return (byte)(m(c, (byte)2) ^ c);
  242.                 }
  243.                 case 0x09: {
  244.                     return (byte)(m(m(m(c, 2), 2), 2) ^ c);
  245.                 }
  246.                 case 0x0B: {
  247.                     return (byte)(m(m(m(c, 2), 2) ^ c, 2) ^ c);
  248.                 }
  249.                 case 0x0D: {
  250.                     return (byte)(m(m(m(c, 2) ^ c, 2), 2) ^ c);
  251.                 }
  252.                 case 0x0E: {
  253.                     return (byte)m(m(m(c, 2) ^ c, 2) ^ c, 2);
  254.                 }
  255.                 default: {
  256.                     throw new RuntimeException("Multiplication error");
  257.                 }
  258.             }
  259.         }
  260.  
  261.         private void shiftRows(byte[] block) {
  262.             byte temp = block[4];
  263.             block[4] = block[5];
  264.             block[5] = block[6];
  265.             block[6] = block[7];
  266.             block[7] = temp;
  267.             block[8] = (byte)(block[8] ^ block[10]);
  268.             block[10] = (byte)(block[8] ^ block[10]);
  269.             block[8] = (byte)(block[8] ^ block[10]);
  270.             block[9] = (byte)(block[9] ^ block[11]);
  271.             block[11] = (byte)(block[9] ^ block[11]);
  272.             block[9] = (byte)(block[9] ^ block[11]);
  273.             temp = block[15];
  274.             block[15] = block[14];
  275.             block[14] = block[13];
  276.             block[13] = block[12];
  277.             block[12] = temp;
  278.         }
  279.        
  280.         private void shiftRowsBack(byte[] block) {
  281.             byte temp = block[7];
  282.             block[7] = block[6];
  283.             block[6] = block[5];
  284.             block[5] = block[4];
  285.             block[4] = temp;
  286.             block[11] = (byte)(block[11] ^ block[9]);
  287.             block[9] = (byte)(block[11] ^ block[9]);
  288.             block[11] = (byte)(block[11] ^ block[9]);
  289.             block[10] = (byte)(block[10] ^ block[8]);
  290.             block[8] = (byte)(block[10] ^ block[8]);
  291.             block[10] = (byte)(block[10] ^ block[8]);
  292.             temp = block[12];
  293.             block[12] = block[13];
  294.             block[13] = block[14];
  295.             block[14] = block[15];
  296.             block[15] = temp;
  297.         }
  298.     }
  299.    
  300.     //AES-128 key: 128
  301.     private static final byte[][] rcon = new byte[][]{
  302.         {0x01, 0, 0, 0}, {0x02, 0x00, 0x00, 0x00}, {0x04, 0x00, 0x00, 0x00}, {0x08, 0x00, 0x00, 0x00}, {0x10, 0x00, 0x00, 0x00}, {0x20, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00}, {(byte)0x80, 0x00, 0x00, 0x00}, {(byte)0x1b, 0x00, 0x00, 0x00}, {(byte)0x36, 0x00, 0x00, 0x00}
  303.     };
  304.  
  305.     private static final byte[][] mix = new byte[][]{
  306.         {0x02, 0x03, 0x01, 0x01},
  307.         {0x01, 0x02, 0x03, 0x01},
  308.         {0x01, 0x01, 0x02, 0x03},
  309.         {0x03, 0x01, 0x01, 0x02}
  310.     };
  311.    
  312.     private static final byte[][] inv_mix = new byte[][]{
  313.         {0x0E, 0x0B, 0x0D, 0x09},
  314.         {0x09, 0x0E, 0x0B, 0x0D},
  315.         {0x0D, 0x09, 0x0E, 0x0B},
  316.         {0x0B, 0x0D, 0x09, 0x0E}
  317.     };
  318.  
  319.     private static final byte[] s = new byte[]{
  320.         (byte)0x63, (byte)0x7C, (byte)0x77, (byte)0x7B, (byte)0xF2, (byte)0x6B, (byte)0x6F, (byte)0xC5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2B, (byte)0xFE, (byte)0xD7, (byte)0xAB, (byte)0x76,
  321.         (byte)0xCA, (byte)0x82, (byte)0xC9, (byte)0x7D, (byte)0xFA, (byte)0x59, (byte)0x47, (byte)0xF0, (byte)0xAD, (byte)0xD4, (byte)0xA2, (byte)0xAF, (byte)0x9C, (byte)0xA4, (byte)0x72, (byte)0xC0,
  322.         (byte)0xB7, (byte)0xFD, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3F, (byte)0xF7, (byte)0xCC, (byte)0x34, (byte)0xA5, (byte)0xE5, (byte)0xF1, (byte)0x71, (byte)0xD8, (byte)0x31, (byte)0x15,
  323.         (byte)0x04, (byte)0xC7, (byte)0x23, (byte)0xC3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9A, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xE2, (byte)0xEB, (byte)0x27, (byte)0xB2, (byte)0x75,
  324.         (byte)0x09, (byte)0x83, (byte)0x2C, (byte)0x1A, (byte)0x1B, (byte)0x6E, (byte)0x5A, (byte)0xA0, (byte)0x52, (byte)0x3B, (byte)0xD6, (byte)0xB3, (byte)0x29, (byte)0xE3, (byte)0x2F, (byte)0x84,
  325.         (byte)0x53, (byte)0xD1, (byte)0x00, (byte)0xED, (byte)0x20, (byte)0xFC, (byte)0xB1, (byte)0x5B, (byte)0x6A, (byte)0xCB, (byte)0xBE, (byte)0x39, (byte)0x4A, (byte)0x4C, (byte)0x58, (byte)0xCF,
  326.         (byte)0xD0, (byte)0xEF, (byte)0xAA, (byte)0xFB, (byte)0x43, (byte)0x4D, (byte)0x33, (byte)0x85, (byte)0x45, (byte)0xF9, (byte)0x02, (byte)0x7F, (byte)0x50, (byte)0x3C, (byte)0x9F, (byte)0xA8,
  327.         (byte)0x51, (byte)0xA3, (byte)0x40, (byte)0x8F, (byte)0x92, (byte)0x9D, (byte)0x38, (byte)0xF5, (byte)0xBC, (byte)0xB6, (byte)0xDA, (byte)0x21, (byte)0x10, (byte)0xFF, (byte)0xF3, (byte)0xD2,
  328.         (byte)0xCD, (byte)0x0C, (byte)0x13, (byte)0xEC, (byte)0x5F, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xC4, (byte)0xA7, (byte)0x7E, (byte)0x3D, (byte)0x64, (byte)0x5D, (byte)0x19, (byte)0x73,
  329.         (byte)0x60, (byte)0x81, (byte)0x4F, (byte)0xDC, (byte)0x22, (byte)0x2A, (byte)0x90, (byte)0x88, (byte)0x46, (byte)0xEE, (byte)0xB8, (byte)0x14, (byte)0xDE, (byte)0x5E, (byte)0x0B, (byte)0xDB,
  330.         (byte)0xE0, (byte)0x32, (byte)0x3A, (byte)0x0A, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5C, (byte)0xC2, (byte)0xD3, (byte)0xAC, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xE4, (byte)0x79,
  331.         (byte)0xE7, (byte)0xC8, (byte)0x37, (byte)0x6D, (byte)0x8D, (byte)0xD5, (byte)0x4E, (byte)0xA9, (byte)0x6C, (byte)0x56, (byte)0xF4, (byte)0xEA, (byte)0x65, (byte)0x7A, (byte)0xAE, (byte)0x08,
  332.         (byte)0xBA, (byte)0x78, (byte)0x25, (byte)0x2E, (byte)0x1C, (byte)0xA6, (byte)0xB4, (byte)0xC6, (byte)0xE8, (byte)0xDD, (byte)0x74, (byte)0x1F, (byte)0x4B, (byte)0xBD, (byte)0x8B, (byte)0x8A,
  333.         (byte)0x70, (byte)0x3E, (byte)0xB5, (byte)0x66, (byte)0x48, (byte)0x03, (byte)0xF6, (byte)0x0E, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xB9, (byte)0x86, (byte)0xC1, (byte)0x1D, (byte)0x9E,
  334.         (byte)0xE1, (byte)0xF8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xD9, (byte)0x8E, (byte)0x94, (byte)0x9B, (byte)0x1E, (byte)0x87, (byte)0xE9, (byte)0xCE, (byte)0x55, (byte)0x28, (byte)0xDF,
  335.         (byte)0x8C, (byte)0xA1, (byte)0x89, (byte)0x0D, (byte)0xBF, (byte)0xE6, (byte)0x42, (byte)0x68, (byte)0x41, (byte)0x99, (byte)0x2D, (byte)0x0F, (byte)0xB0, (byte)0x54, (byte)0xBB, (byte)0x16
  336.     };
  337.  
  338.     private static final byte[] inv_s = new byte[]{
  339.         (byte)0x52, (byte)0x09, (byte)0x6A, (byte)0xD5, (byte)0x30, (byte)0x36, (byte)0xA5, (byte)0x38, (byte)0xBF, (byte)0x40, (byte)0xA3, (byte)0x9E, (byte)0x81, (byte)0xF3, (byte)0xD7, (byte)0xFB,
  340.         (byte)0x7C, (byte)0xE3, (byte)0x39, (byte)0x82, (byte)0x9B, (byte)0x2F, (byte)0xFF, (byte)0x87, (byte)0x34, (byte)0x8E, (byte)0x43, (byte)0x44, (byte)0xC4, (byte)0xDE, (byte)0xE9, (byte)0xCB,
  341.         (byte)0x54, (byte)0x7B, (byte)0x94, (byte)0x32, (byte)0xA6, (byte)0xC2, (byte)0x23, (byte)0x3D, (byte)0xEE, (byte)0x4C, (byte)0x95, (byte)0x0B, (byte)0x42, (byte)0xFA, (byte)0xC3, (byte)0x4E,
  342.         (byte)0x08, (byte)0x2E, (byte)0xA1, (byte)0x66, (byte)0x28, (byte)0xD9, (byte)0x24, (byte)0xB2, (byte)0x76, (byte)0x5B, (byte)0xA2, (byte)0x49, (byte)0x6D, (byte)0x8B, (byte)0xD1, (byte)0x25,
  343.         (byte)0x72, (byte)0xF8, (byte)0xF6, (byte)0x64, (byte)0x86, (byte)0x68, (byte)0x98, (byte)0x16, (byte)0xD4, (byte)0xA4, (byte)0x5C, (byte)0xCC, (byte)0x5D, (byte)0x65, (byte)0xB6, (byte)0x92,
  344.         (byte)0x6C, (byte)0x70, (byte)0x48, (byte)0x50, (byte)0xFD, (byte)0xED, (byte)0xB9, (byte)0xDA, (byte)0x5E, (byte)0x15, (byte)0x46, (byte)0x57, (byte)0xA7, (byte)0x8D, (byte)0x9D, (byte)0x84,
  345.         (byte)0x90, (byte)0xD8, (byte)0xAB, (byte)0x00, (byte)0x8C, (byte)0xBC, (byte)0xD3, (byte)0x0A, (byte)0xF7, (byte)0xE4, (byte)0x58, (byte)0x05, (byte)0xB8, (byte)0xB3, (byte)0x45, (byte)0x06,
  346.         (byte)0xD0, (byte)0x2C, (byte)0x1E, (byte)0x8F, (byte)0xCA, (byte)0x3F, (byte)0x0F, (byte)0x02, (byte)0xC1, (byte)0xAF, (byte)0xBD, (byte)0x03, (byte)0x01, (byte)0x13, (byte)0x8A, (byte)0x6B,
  347.         (byte)0x3A, (byte)0x91, (byte)0x11, (byte)0x41, (byte)0x4F, (byte)0x67, (byte)0xDC, (byte)0xEA, (byte)0x97, (byte)0xF2, (byte)0xCF, (byte)0xCE, (byte)0xF0, (byte)0xB4, (byte)0xE6, (byte)0x73,
  348.         (byte)0x96, (byte)0xAC, (byte)0x74, (byte)0x22, (byte)0xE7, (byte)0xAD, (byte)0x35, (byte)0x85, (byte)0xE2, (byte)0xF9, (byte)0x37, (byte)0xE8, (byte)0x1C, (byte)0x75, (byte)0xDF, (byte)0x6E,
  349.         (byte)0x47, (byte)0xF1, (byte)0x1A, (byte)0x71, (byte)0x1D, (byte)0x29, (byte)0xC5, (byte)0x89, (byte)0x6F, (byte)0xB7, (byte)0x62, (byte)0x0E, (byte)0xAA, (byte)0x18, (byte)0xBE, (byte)0x1B,
  350.         (byte)0xFC, (byte)0x56, (byte)0x3E, (byte)0x4B, (byte)0xC6, (byte)0xD2, (byte)0x79, (byte)0x20, (byte)0x9A, (byte)0xDB, (byte)0xC0, (byte)0xFE, (byte)0x78, (byte)0xCD, (byte)0x5A, (byte)0xF4,
  351.         (byte)0x1F, (byte)0xDD, (byte)0xA8, (byte)0x33, (byte)0x88, (byte)0x07, (byte)0xC7, (byte)0x31, (byte)0xB1, (byte)0x12, (byte)0x10, (byte)0x59, (byte)0x27, (byte)0x80, (byte)0xEC, (byte)0x5F,
  352.         (byte)0x60, (byte)0x51, (byte)0x7F, (byte)0xA9, (byte)0x19, (byte)0xB5, (byte)0x4A, (byte)0x0D, (byte)0x2D, (byte)0xE5, (byte)0x7A, (byte)0x9F, (byte)0x93, (byte)0xC9, (byte)0x9C, (byte)0xEF,
  353.         (byte)0xA0, (byte)0xE0, (byte)0x3B, (byte)0x4D, (byte)0xAE, (byte)0x2A, (byte)0xF5, (byte)0xB0, (byte)0xC8, (byte)0xEB, (byte)0xBB, (byte)0x3C, (byte)0x83, (byte)0x53, (byte)0x99, (byte)0x61,
  354.         (byte)0x17, (byte)0x2B, (byte)0x04, (byte)0x7E, (byte)0xBA, (byte)0x77, (byte)0xD6, (byte)0x26, (byte)0xE1, (byte)0x69, (byte)0x14, (byte)0x63, (byte)0x55, (byte)0x21, (byte)0x0C, (byte)0x7D
  355.     };
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement