| 1 | 769 | jeremybenn | /* DES.java --
 | 
      
         | 2 |  |  |    Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
 | 
      
         | 3 |  |  |  
 | 
      
         | 4 |  |  | This file is a part of GNU Classpath.
 | 
      
         | 5 |  |  |  
 | 
      
         | 6 |  |  | GNU Classpath is free software; you can redistribute it and/or modify
 | 
      
         | 7 |  |  | it under the terms of the GNU General Public License as published by
 | 
      
         | 8 |  |  | the Free Software Foundation; either version 2 of the License, or (at
 | 
      
         | 9 |  |  | your option) any later version.
 | 
      
         | 10 |  |  |  
 | 
      
         | 11 |  |  | GNU Classpath is distributed in the hope that it will be useful, but
 | 
      
         | 12 |  |  | WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
      
         | 13 |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
      
         | 14 |  |  | General Public License for more details.
 | 
      
         | 15 |  |  |  
 | 
      
         | 16 |  |  | You should have received a copy of the GNU General Public License
 | 
      
         | 17 |  |  | along with GNU Classpath; if not, write to the Free Software
 | 
      
         | 18 |  |  | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 | 
      
         | 19 |  |  | USA
 | 
      
         | 20 |  |  |  
 | 
      
         | 21 |  |  | Linking this library statically or dynamically with other modules is
 | 
      
         | 22 |  |  | making a combined work based on this library.  Thus, the terms and
 | 
      
         | 23 |  |  | conditions of the GNU General Public License cover the whole
 | 
      
         | 24 |  |  | combination.
 | 
      
         | 25 |  |  |  
 | 
      
         | 26 |  |  | As a special exception, the copyright holders of this library give you
 | 
      
         | 27 |  |  | permission to link this library with independent modules to produce an
 | 
      
         | 28 |  |  | executable, regardless of the license terms of these independent
 | 
      
         | 29 |  |  | modules, and to copy and distribute the resulting executable under
 | 
      
         | 30 |  |  | terms of your choice, provided that you also meet, for each linked
 | 
      
         | 31 |  |  | independent module, the terms and conditions of the license of that
 | 
      
         | 32 |  |  | module.  An independent module is a module which is not derived from
 | 
      
         | 33 |  |  | or based on this library.  If you modify this library, you may extend
 | 
      
         | 34 |  |  | this exception to your version of the library, but you are not
 | 
      
         | 35 |  |  | obligated to do so.  If you do not wish to do so, delete this
 | 
      
         | 36 |  |  | exception statement from your version.  */
 | 
      
         | 37 |  |  |  
 | 
      
         | 38 |  |  |  
 | 
      
         | 39 |  |  | package gnu.javax.crypto.cipher;
 | 
      
         | 40 |  |  |  
 | 
      
         | 41 |  |  | import gnu.java.security.Registry;
 | 
      
         | 42 |  |  | import gnu.java.security.Properties;
 | 
      
         | 43 |  |  | import gnu.java.security.util.Util;
 | 
      
         | 44 |  |  |  
 | 
      
         | 45 |  |  | import java.security.InvalidKeyException;
 | 
      
         | 46 |  |  | import java.util.Arrays;
 | 
      
         | 47 |  |  | import java.util.Collections;
 | 
      
         | 48 |  |  | import java.util.Iterator;
 | 
      
         | 49 |  |  |  
 | 
      
         | 50 |  |  | /**
 | 
      
         | 51 |  |  |  * The Data Encryption Standard. DES is a 64-bit block cipher with a 56-bit
 | 
      
         | 52 |  |  |  * key, developed by IBM in the 1970's for the standardization process begun by
 | 
      
         | 53 |  |  |  * the National Bureau of Standards (now NIST).
 | 
      
         | 54 |  |  |  * <p>
 | 
      
         | 55 |  |  |  * New applications should not use DES except for compatibility.
 | 
      
         | 56 |  |  |  * <p>
 | 
      
         | 57 |  |  |  * This version is based upon the description and sample implementation in
 | 
      
         | 58 |  |  |  * [1].
 | 
      
         | 59 |  |  |  * <p>
 | 
      
         | 60 |  |  |  * References:
 | 
      
         | 61 |  |  |  * <ol>
 | 
      
         | 62 |  |  |  *    <li>Bruce Schneier, <i>Applied Cryptography: Protocols, Algorithms, and
 | 
      
         | 63 |  |  |  *    Source Code in C, Second Edition</i>. (1996 John Wiley and Sons) ISBN
 | 
      
         | 64 |  |  |  *    0-471-11709-9. Pages 265--301, 623--632.</li>
 | 
      
         | 65 |  |  |  * </ol>
 | 
      
         | 66 |  |  |  */
 | 
      
         | 67 |  |  | public class DES
 | 
      
         | 68 |  |  |     extends BaseCipher
 | 
      
         | 69 |  |  | {
 | 
      
         | 70 |  |  |   /** DES operates on 64 bit blocks. */
 | 
      
         | 71 |  |  |   public static final int BLOCK_SIZE = 8;
 | 
      
         | 72 |  |  |   /** DES uses 56 bits of a 64 bit parity-adjusted key. */
 | 
      
         | 73 |  |  |   public static final int KEY_SIZE = 8;
 | 
      
         | 74 |  |  |   // S-Boxes 1 through 8.
 | 
      
         | 75 |  |  |   private static final int[] SP1 = new int[] {
 | 
      
         | 76 |  |  |       0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
 | 
      
         | 77 |  |  |       0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
 | 
      
         | 78 |  |  |       0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
 | 
      
         | 79 |  |  |       0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
 | 
      
         | 80 |  |  |       0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
 | 
      
         | 81 |  |  |       0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
 | 
      
         | 82 |  |  |       0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
 | 
      
         | 83 |  |  |       0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
 | 
      
         | 84 |  |  |       0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
 | 
      
         | 85 |  |  |       0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
 | 
      
         | 86 |  |  |       0x00010004, 0x00010400, 0x00000000, 0x01010004 };
 | 
      
         | 87 |  |  |   private static final int[] SP2 = new int[] {
 | 
      
         | 88 |  |  |       0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
 | 
      
         | 89 |  |  |       0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
 | 
      
         | 90 |  |  |       0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
 | 
      
         | 91 |  |  |       0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
 | 
      
         | 92 |  |  |       0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
 | 
      
         | 93 |  |  |       0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
 | 
      
         | 94 |  |  |       0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
 | 
      
         | 95 |  |  |       0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
 | 
      
         | 96 |  |  |       0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
 | 
      
         | 97 |  |  |       0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
 | 
      
         | 98 |  |  |       0x80000000, 0x80100020, 0x80108020, 0x00108000 };
 | 
      
         | 99 |  |  |   private static final int[] SP3 = new int[] {
 | 
      
         | 100 |  |  |       0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
 | 
      
         | 101 |  |  |       0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
 | 
      
         | 102 |  |  |       0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
 | 
      
         | 103 |  |  |       0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
 | 
      
         | 104 |  |  |       0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
 | 
      
         | 105 |  |  |       0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
 | 
      
         | 106 |  |  |       0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
 | 
      
         | 107 |  |  |       0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
 | 
      
         | 108 |  |  |       0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
 | 
      
         | 109 |  |  |       0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
 | 
      
         | 110 |  |  |       0x00020208, 0x00000008, 0x08020008, 0x00020200 };
 | 
      
         | 111 |  |  |   private static final int[] SP4 = new int[] {
 | 
      
         | 112 |  |  |       0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
 | 
      
         | 113 |  |  |       0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
 | 
      
         | 114 |  |  |       0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
 | 
      
         | 115 |  |  |       0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
 | 
      
         | 116 |  |  |       0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
 | 
      
         | 117 |  |  |       0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
 | 
      
         | 118 |  |  |       0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
 | 
      
         | 119 |  |  |       0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
 | 
      
         | 120 |  |  |       0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
 | 
      
         | 121 |  |  |       0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
 | 
      
         | 122 |  |  |       0x00000080, 0x00800000, 0x00002000, 0x00802080 };
 | 
      
         | 123 |  |  |   private static final int[] SP5 = new int[] {
 | 
      
         | 124 |  |  |       0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
 | 
      
         | 125 |  |  |       0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
 | 
      
         | 126 |  |  |       0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
 | 
      
         | 127 |  |  |       0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
 | 
      
         | 128 |  |  |       0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
 | 
      
         | 129 |  |  |       0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
 | 
      
         | 130 |  |  |       0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
 | 
      
         | 131 |  |  |       0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
 | 
      
         | 132 |  |  |       0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
 | 
      
         | 133 |  |  |       0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
 | 
      
         | 134 |  |  |       0x00000000, 0x40080000, 0x02080100, 0x40000100 };
 | 
      
         | 135 |  |  |   private static final int[] SP6 = new int[] {
 | 
      
         | 136 |  |  |       0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
 | 
      
         | 137 |  |  |       0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
 | 
      
         | 138 |  |  |       0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
 | 
      
         | 139 |  |  |       0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
 | 
      
         | 140 |  |  |       0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
 | 
      
         | 141 |  |  |       0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
 | 
      
         | 142 |  |  |       0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
 | 
      
         | 143 |  |  |       0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
 | 
      
         | 144 |  |  |       0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
 | 
      
         | 145 |  |  |       0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
 | 
      
         | 146 |  |  |       0x20404000, 0x20000000, 0x00400010, 0x20004010 };
 | 
      
         | 147 |  |  |   private static final int[] SP7 = new int[] {
 | 
      
         | 148 |  |  |       0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
 | 
      
         | 149 |  |  |       0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
 | 
      
         | 150 |  |  |       0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
 | 
      
         | 151 |  |  |       0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
 | 
      
         | 152 |  |  |       0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
 | 
      
         | 153 |  |  |       0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
 | 
      
         | 154 |  |  |       0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
 | 
      
         | 155 |  |  |       0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
 | 
      
         | 156 |  |  |       0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
 | 
      
         | 157 |  |  |       0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
 | 
      
         | 158 |  |  |       0x04000002, 0x04000800, 0x00000800, 0x00200002 };
 | 
      
         | 159 |  |  |   private static final int[] SP8 = new int[] {
 | 
      
         | 160 |  |  |       0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
 | 
      
         | 161 |  |  |       0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
 | 
      
         | 162 |  |  |       0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
 | 
      
         | 163 |  |  |       0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
 | 
      
         | 164 |  |  |       0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
 | 
      
         | 165 |  |  |       0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
 | 
      
         | 166 |  |  |       0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
 | 
      
         | 167 |  |  |       0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
 | 
      
         | 168 |  |  |       0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
 | 
      
         | 169 |  |  |       0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
 | 
      
         | 170 |  |  |       0x00001040, 0x00040040, 0x10000000, 0x10041000 };
 | 
      
         | 171 |  |  |   /**
 | 
      
         | 172 |  |  |    * Constants that help in determining whether or not a byte array is parity
 | 
      
         | 173 |  |  |    * adjusted.
 | 
      
         | 174 |  |  |    */
 | 
      
         | 175 |  |  |   private static final byte[] PARITY = {
 | 
      
         | 176 |  |  |       8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8,
 | 
      
         | 177 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 3,
 | 
      
         | 178 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 179 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 180 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 181 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 182 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 183 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 184 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 185 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 186 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 187 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 188 |  |  |       8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
 | 
      
         | 189 |  |  |       0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 190 |  |  |       4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
 | 
      
         | 191 |  |  |       8, 5, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 6, 8 };
 | 
      
         | 192 |  |  |   // Key schedule constants.
 | 
      
         | 193 |  |  |   private static final byte[] ROTARS = {
 | 
      
         | 194 |  |  |       1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
 | 
      
         | 195 |  |  |   private static final byte[] PC1 = {
 | 
      
         | 196 |  |  |       56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,  9,  1,
 | 
      
         | 197 |  |  |       58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35, 62, 54, 46, 38,
 | 
      
         | 198 |  |  |       30, 22, 14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 60, 52, 44, 36,
 | 
      
         | 199 |  |  |       28, 20, 12,  4, 27, 19, 11,  3 };
 | 
      
         | 200 |  |  |   private static final byte[] PC2 = {
 | 
      
         | 201 |  |  |       13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9, 22, 18, 11,  3,
 | 
      
         | 202 |  |  |       25,  7, 15,  6, 26, 19, 12,  1, 40, 51, 30, 36, 46, 54, 29, 39,
 | 
      
         | 203 |  |  |       50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
 | 
      
         | 204 |  |  |   /**
 | 
      
         | 205 |  |  |    * Weak keys (parity adjusted): If all the bits in each half are either 0
 | 
      
         | 206 |  |  |    * or 1, then the key used for any cycle of the algorithm is the same as
 | 
      
         | 207 |  |  |    * all other cycles.
 | 
      
         | 208 |  |  |    */
 | 
      
         | 209 |  |  |   public static final byte[][] WEAK_KEYS = {
 | 
      
         | 210 |  |  |       Util.toBytesFromString("0101010101010101"),
 | 
      
         | 211 |  |  |       Util.toBytesFromString("01010101FEFEFEFE"),
 | 
      
         | 212 |  |  |       Util.toBytesFromString("FEFEFEFE01010101"),
 | 
      
         | 213 |  |  |       Util.toBytesFromString("FEFEFEFEFEFEFEFE") };
 | 
      
         | 214 |  |  |   /**
 | 
      
         | 215 |  |  |    * Semi-weak keys (parity adjusted):  Some pairs of keys encrypt plain text
 | 
      
         | 216 |  |  |    * to identical cipher text. In other words, one key in the pair can decrypt
 | 
      
         | 217 |  |  |    * messages that were encrypted with the other key. These keys are called
 | 
      
         | 218 |  |  |    * semi-weak keys. This occurs because instead of 16 different sub-keys being
 | 
      
         | 219 |  |  |    * generated, these semi-weak keys produce only two different sub-keys.
 | 
      
         | 220 |  |  |    */
 | 
      
         | 221 |  |  |   public static final byte[][] SEMIWEAK_KEYS = {
 | 
      
         | 222 |  |  |       Util.toBytesFromString("01FE01FE01FE01FE"),
 | 
      
         | 223 |  |  |       Util.toBytesFromString("FE01FE01FE01FE01"),
 | 
      
         | 224 |  |  |       Util.toBytesFromString("1FE01FE00EF10EF1"),
 | 
      
         | 225 |  |  |       Util.toBytesFromString("E01FE01FF10EF10E"),
 | 
      
         | 226 |  |  |       Util.toBytesFromString("01E001E001F101F1"),
 | 
      
         | 227 |  |  |       Util.toBytesFromString("E001E001F101F101"),
 | 
      
         | 228 |  |  |       Util.toBytesFromString("1FFE1FFE0EFE0EFE"),
 | 
      
         | 229 |  |  |       Util.toBytesFromString("FE1FFE1FFE0EFE0E"),
 | 
      
         | 230 |  |  |       Util.toBytesFromString("011F011F010E010E"),
 | 
      
         | 231 |  |  |       Util.toBytesFromString("1F011F010E010E01"),
 | 
      
         | 232 |  |  |       Util.toBytesFromString("E0FEE0FEF1FEF1FE"),
 | 
      
         | 233 |  |  |       Util.toBytesFromString("FEE0FEE0FEF1FEF1") };
 | 
      
         | 234 |  |  |   /** Possible weak keys (parity adjusted) --produce 4 instead of 16 subkeys. */
 | 
      
         | 235 |  |  |   public static final byte[][] POSSIBLE_WEAK_KEYS = {
 | 
      
         | 236 |  |  |       Util.toBytesFromString("1F1F01010E0E0101"),
 | 
      
         | 237 |  |  |       Util.toBytesFromString("011F1F01010E0E01"),
 | 
      
         | 238 |  |  |       Util.toBytesFromString("1F01011F0E01010E"),
 | 
      
         | 239 |  |  |       Util.toBytesFromString("01011F1F01010E0E"),
 | 
      
         | 240 |  |  |       Util.toBytesFromString("E0E00101F1F10101"),
 | 
      
         | 241 |  |  |       Util.toBytesFromString("FEFE0101FEFE0101"),
 | 
      
         | 242 |  |  |       Util.toBytesFromString("FEE01F01FEF10E01"),
 | 
      
         | 243 |  |  |       Util.toBytesFromString("E0FE1F01F1FE0E01"),
 | 
      
         | 244 |  |  |       Util.toBytesFromString("FEE0011FFEF1010E"),
 | 
      
         | 245 |  |  |       Util.toBytesFromString("E0FE011FF1FE010E"),
 | 
      
         | 246 |  |  |       Util.toBytesFromString("E0E01F1FF1F10E0E"),
 | 
      
         | 247 |  |  |       Util.toBytesFromString("FEFE1F1FFEFE0E0E"),
 | 
      
         | 248 |  |  |       Util.toBytesFromString("1F1F01010E0E0101"),
 | 
      
         | 249 |  |  |       Util.toBytesFromString("011F1F01010E0E01"),
 | 
      
         | 250 |  |  |       Util.toBytesFromString("1F01011F0E01010E"),
 | 
      
         | 251 |  |  |       Util.toBytesFromString("01011F1F01010E0E"),
 | 
      
         | 252 |  |  |       Util.toBytesFromString("01E0E00101F1F101"),
 | 
      
         | 253 |  |  |       Util.toBytesFromString("1FFEE0010EFEF001"),
 | 
      
         | 254 |  |  |       Util.toBytesFromString("1FE0FE010EF1FE01"),
 | 
      
         | 255 |  |  |       Util.toBytesFromString("01FEFE0101FEFE01"),
 | 
      
         | 256 |  |  |       Util.toBytesFromString("1FE0E01F0EF1F10E"),
 | 
      
         | 257 |  |  |       Util.toBytesFromString("01FEE01F01FEF10E"),
 | 
      
         | 258 |  |  |       Util.toBytesFromString("01E0FE1F01F1FE0E"),
 | 
      
         | 259 |  |  |       Util.toBytesFromString("1FFEFE1F0EFEFE0E"),
 | 
      
         | 260 |  |  |  
 | 
      
         | 261 |  |  |       Util.toBytesFromString("E00101E0F10101F1"),
 | 
      
         | 262 |  |  |       Util.toBytesFromString("FE1F01E0FE0E0EF1"),
 | 
      
         | 263 |  |  |       Util.toBytesFromString("FE011FE0FE010EF1"),
 | 
      
         | 264 |  |  |       Util.toBytesFromString("E01F1FE0F10E0EF1"),
 | 
      
         | 265 |  |  |       Util.toBytesFromString("FE0101FEFE0101FE"),
 | 
      
         | 266 |  |  |       Util.toBytesFromString("E01F01FEF10E01FE"),
 | 
      
         | 267 |  |  |       Util.toBytesFromString("E0011FFEF1010EFE"),
 | 
      
         | 268 |  |  |       Util.toBytesFromString("FE1F1FFEFE0E0EFE"),
 | 
      
         | 269 |  |  |       Util.toBytesFromString("1FFE01E00EFE01F1"),
 | 
      
         | 270 |  |  |       Util.toBytesFromString("01FE1FE001FE0EF1"),
 | 
      
         | 271 |  |  |       Util.toBytesFromString("1FE001FE0EF101FE"),
 | 
      
         | 272 |  |  |       Util.toBytesFromString("01E01FFE01F10EFE"),
 | 
      
         | 273 |  |  |       Util.toBytesFromString("0101E0E00101F1F1"),
 | 
      
         | 274 |  |  |       Util.toBytesFromString("1F1FE0E00E0EF1F1"),
 | 
      
         | 275 |  |  |       Util.toBytesFromString("1F01FEE00E01FEF1"),
 | 
      
         | 276 |  |  |       Util.toBytesFromString("011FFEE0010EFEF1"),
 | 
      
         | 277 |  |  |       Util.toBytesFromString("1F01E0FE0E01F1FE"),
 | 
      
         | 278 |  |  |       Util.toBytesFromString("011FE0FE010EF1FE"),
 | 
      
         | 279 |  |  |       Util.toBytesFromString("0101FEFE0001FEFE"),
 | 
      
         | 280 |  |  |       Util.toBytesFromString("1F1FFEFE0E0EFEFE"),
 | 
      
         | 281 |  |  |       Util.toBytesFromString("FEFEE0E0FEFEF1F1"),
 | 
      
         | 282 |  |  |       Util.toBytesFromString("E0FEFEE0F1FEFEF1"),
 | 
      
         | 283 |  |  |       Util.toBytesFromString("FEE0E0FEFEF1F1FE"),
 | 
      
         | 284 |  |  |       Util.toBytesFromString("E0E0FEFEF1F1FEFE") };
 | 
      
         | 285 |  |  |  
 | 
      
         | 286 |  |  |   /** Default 0-argument constructor. */
 | 
      
         | 287 |  |  |   public DES()
 | 
      
         | 288 |  |  |   {
 | 
      
         | 289 |  |  |     super(Registry.DES_CIPHER, BLOCK_SIZE, KEY_SIZE);
 | 
      
         | 290 |  |  |   }
 | 
      
         | 291 |  |  |  
 | 
      
         | 292 |  |  |   /**
 | 
      
         | 293 |  |  |    * Adjust the parity for a raw key array. This essentially means that each
 | 
      
         | 294 |  |  |    * byte in the array will have an odd number of '1' bits (the last bit in
 | 
      
         | 295 |  |  |    * each byte is unused.
 | 
      
         | 296 |  |  |    *
 | 
      
         | 297 |  |  |    * @param kb The key array, to be parity-adjusted.
 | 
      
         | 298 |  |  |    * @param offset The starting index into the key bytes.
 | 
      
         | 299 |  |  |    */
 | 
      
         | 300 |  |  |   public static void adjustParity(byte[] kb, int offset)
 | 
      
         | 301 |  |  |   {
 | 
      
         | 302 |  |  |     for (int i = offset; i < offset + KEY_SIZE; i++)
 | 
      
         | 303 |  |  |       kb[i] ^= (PARITY[kb[i] & 0xff] == 8) ? 1 : 0;
 | 
      
         | 304 |  |  |   }
 | 
      
         | 305 |  |  |  
 | 
      
         | 306 |  |  |   /**
 | 
      
         | 307 |  |  |    * Test if a byte array, which must be at least 8 bytes long, is parity
 | 
      
         | 308 |  |  |    * adjusted.
 | 
      
         | 309 |  |  |    *
 | 
      
         | 310 |  |  |    * @param kb The key bytes.
 | 
      
         | 311 |  |  |    * @param offset The starting index into the key bytes.
 | 
      
         | 312 |  |  |    * @return <code>true</code> if the first 8 bytes of <i>kb</i> have been
 | 
      
         | 313 |  |  |    * parity adjusted. <code>false</code> otherwise.
 | 
      
         | 314 |  |  |    */
 | 
      
         | 315 |  |  |   public static boolean isParityAdjusted(byte[] kb, int offset)
 | 
      
         | 316 |  |  |   {
 | 
      
         | 317 |  |  |     int w = 0x88888888;
 | 
      
         | 318 |  |  |     int n = PARITY[kb[offset + 0] & 0xff];
 | 
      
         | 319 |  |  |     n <<= 4;
 | 
      
         | 320 |  |  |     n |= PARITY[kb[offset + 1] & 0xff];
 | 
      
         | 321 |  |  |     n <<= 4;
 | 
      
         | 322 |  |  |     n |= PARITY[kb[offset + 2] & 0xff];
 | 
      
         | 323 |  |  |     n <<= 4;
 | 
      
         | 324 |  |  |     n |= PARITY[kb[offset + 3] & 0xff];
 | 
      
         | 325 |  |  |     n <<= 4;
 | 
      
         | 326 |  |  |     n |= PARITY[kb[offset + 4] & 0xff];
 | 
      
         | 327 |  |  |     n <<= 4;
 | 
      
         | 328 |  |  |     n |= PARITY[kb[offset + 5] & 0xff];
 | 
      
         | 329 |  |  |     n <<= 4;
 | 
      
         | 330 |  |  |     n |= PARITY[kb[offset + 6] & 0xff];
 | 
      
         | 331 |  |  |     n <<= 4;
 | 
      
         | 332 |  |  |     n |= PARITY[kb[offset + 7] & 0xff];
 | 
      
         | 333 |  |  |     return (n & w) == 0;
 | 
      
         | 334 |  |  |   }
 | 
      
         | 335 |  |  |  
 | 
      
         | 336 |  |  |   /**
 | 
      
         | 337 |  |  |    * Test if a key is a weak key.
 | 
      
         | 338 |  |  |    *
 | 
      
         | 339 |  |  |    * @param kb The key to test.
 | 
      
         | 340 |  |  |    * @return <code>true</code> if the key is weak.
 | 
      
         | 341 |  |  |    */
 | 
      
         | 342 |  |  |   public static boolean isWeak(byte[] kb)
 | 
      
         | 343 |  |  |   {
 | 
      
         | 344 |  |  |     for (int i = 0; i < WEAK_KEYS.length; i++)
 | 
      
         | 345 |  |  |       if (Arrays.equals(WEAK_KEYS[i], kb))
 | 
      
         | 346 |  |  |         return true;
 | 
      
         | 347 |  |  |     return false;
 | 
      
         | 348 |  |  |   }
 | 
      
         | 349 |  |  |  
 | 
      
         | 350 |  |  |   /**
 | 
      
         | 351 |  |  |    * Test if a key is a semi-weak key.
 | 
      
         | 352 |  |  |    *
 | 
      
         | 353 |  |  |    * @param kb The key to test.
 | 
      
         | 354 |  |  |    * @return <code>true</code> if this key is semi-weak.
 | 
      
         | 355 |  |  |    */
 | 
      
         | 356 |  |  |   public static boolean isSemiWeak(byte[] kb)
 | 
      
         | 357 |  |  |   {
 | 
      
         | 358 |  |  |     for (int i = 0; i < SEMIWEAK_KEYS.length; i++)
 | 
      
         | 359 |  |  |       if (Arrays.equals(SEMIWEAK_KEYS[i], kb))
 | 
      
         | 360 |  |  |         return true;
 | 
      
         | 361 |  |  |     return false;
 | 
      
         | 362 |  |  |   }
 | 
      
         | 363 |  |  |  
 | 
      
         | 364 |  |  |   /**
 | 
      
         | 365 |  |  |    * Test if the designated byte array represents a possibly weak key.
 | 
      
         | 366 |  |  |    *
 | 
      
         | 367 |  |  |    * @param kb the byte array to test.
 | 
      
         | 368 |  |  |    * @return <code>true</code> if <code>kb</code>represents a possibly weak key.
 | 
      
         | 369 |  |  |    * Returns <code>false</code> otherwise.
 | 
      
         | 370 |  |  |    */
 | 
      
         | 371 |  |  |   public static boolean isPossibleWeak(byte[] kb)
 | 
      
         | 372 |  |  |   {
 | 
      
         | 373 |  |  |     for (int i = 0; i < POSSIBLE_WEAK_KEYS.length; i++)
 | 
      
         | 374 |  |  |       if (Arrays.equals(POSSIBLE_WEAK_KEYS[i], kb))
 | 
      
         | 375 |  |  |         return true;
 | 
      
         | 376 |  |  |     return false;
 | 
      
         | 377 |  |  |   }
 | 
      
         | 378 |  |  |  
 | 
      
         | 379 |  |  |   /**
 | 
      
         | 380 |  |  |    * The core DES function. This is used for both encryption and decryption,
 | 
      
         | 381 |  |  |    * the only difference being the key.
 | 
      
         | 382 |  |  |    *
 | 
      
         | 383 |  |  |    * @param in The input bytes.
 | 
      
         | 384 |  |  |    * @param i The starting offset into the input bytes.
 | 
      
         | 385 |  |  |    * @param out The output bytes.
 | 
      
         | 386 |  |  |    * @param o The starting offset into the output bytes.
 | 
      
         | 387 |  |  |    * @param key The working key.
 | 
      
         | 388 |  |  |    */
 | 
      
         | 389 |  |  |   private static void desFunc(byte[] in, int i, byte[] out, int o, int[] key)
 | 
      
         | 390 |  |  |   {
 | 
      
         | 391 |  |  |     int right, left, work;
 | 
      
         | 392 |  |  |     // Load.
 | 
      
         | 393 |  |  |     left =  (in[i++] & 0xff) << 24
 | 
      
         | 394 |  |  |           | (in[i++] & 0xff) << 16
 | 
      
         | 395 |  |  |           | (in[i++] & 0xff) << 8
 | 
      
         | 396 |  |  |           |  in[i++] & 0xff;
 | 
      
         | 397 |  |  |     right = (in[i++] & 0xff) << 24
 | 
      
         | 398 |  |  |           | (in[i++] & 0xff) << 16
 | 
      
         | 399 |  |  |           | (in[i++] & 0xff) << 8
 | 
      
         | 400 |  |  |           |  in[i  ] & 0xff;
 | 
      
         | 401 |  |  |     // Initial permutation.
 | 
      
         | 402 |  |  |     work = ((left >>> 4) ^ right) & 0x0F0F0F0F;
 | 
      
         | 403 |  |  |     left ^= work << 4;
 | 
      
         | 404 |  |  |     right ^= work;
 | 
      
         | 405 |  |  |  
 | 
      
         | 406 |  |  |     work = ((left >>> 16) ^ right) & 0x0000FFFF;
 | 
      
         | 407 |  |  |     left ^= work << 16;
 | 
      
         | 408 |  |  |     right ^= work;
 | 
      
         | 409 |  |  |  
 | 
      
         | 410 |  |  |     work = ((right >>> 2) ^ left) & 0x33333333;
 | 
      
         | 411 |  |  |     right ^= work << 2;
 | 
      
         | 412 |  |  |     left ^= work;
 | 
      
         | 413 |  |  |  
 | 
      
         | 414 |  |  |     work = ((right >>> 8) ^ left) & 0x00FF00FF;
 | 
      
         | 415 |  |  |     right ^= work << 8;
 | 
      
         | 416 |  |  |     left ^= work;
 | 
      
         | 417 |  |  |  
 | 
      
         | 418 |  |  |     right = ((right << 1) | ((right >>> 31) & 1)) & 0xFFFFFFFF;
 | 
      
         | 419 |  |  |     work = (left ^ right) & 0xAAAAAAAA;
 | 
      
         | 420 |  |  |     left ^= work;
 | 
      
         | 421 |  |  |     right ^= work;
 | 
      
         | 422 |  |  |     left = ((left << 1) | ((left >>> 31) & 1)) & 0xFFFFFFFF;
 | 
      
         | 423 |  |  |  
 | 
      
         | 424 |  |  |     int k = 0, t;
 | 
      
         | 425 |  |  |     for (int round = 0; round < 8; round++)
 | 
      
         | 426 |  |  |       {
 | 
      
         | 427 |  |  |         work = right >>> 4 | right << 28;
 | 
      
         | 428 |  |  |         work ^= key[k++];
 | 
      
         | 429 |  |  |         t = SP7[work & 0x3F];
 | 
      
         | 430 |  |  |         work >>>= 8;
 | 
      
         | 431 |  |  |         t |= SP5[work & 0x3F];
 | 
      
         | 432 |  |  |         work >>>= 8;
 | 
      
         | 433 |  |  |         t |= SP3[work & 0x3F];
 | 
      
         | 434 |  |  |         work >>>= 8;
 | 
      
         | 435 |  |  |         t |= SP1[work & 0x3F];
 | 
      
         | 436 |  |  |         work = right ^ key[k++];
 | 
      
         | 437 |  |  |         t |= SP8[work & 0x3F];
 | 
      
         | 438 |  |  |         work >>>= 8;
 | 
      
         | 439 |  |  |         t |= SP6[work & 0x3F];
 | 
      
         | 440 |  |  |         work >>>= 8;
 | 
      
         | 441 |  |  |         t |= SP4[work & 0x3F];
 | 
      
         | 442 |  |  |         work >>>= 8;
 | 
      
         | 443 |  |  |         t |= SP2[work & 0x3F];
 | 
      
         | 444 |  |  |         left ^= t;
 | 
      
         | 445 |  |  |  
 | 
      
         | 446 |  |  |         work = left >>> 4 | left << 28;
 | 
      
         | 447 |  |  |         work ^= key[k++];
 | 
      
         | 448 |  |  |         t = SP7[work & 0x3F];
 | 
      
         | 449 |  |  |         work >>>= 8;
 | 
      
         | 450 |  |  |         t |= SP5[work & 0x3F];
 | 
      
         | 451 |  |  |         work >>>= 8;
 | 
      
         | 452 |  |  |         t |= SP3[work & 0x3F];
 | 
      
         | 453 |  |  |         work >>>= 8;
 | 
      
         | 454 |  |  |         t |= SP1[work & 0x3F];
 | 
      
         | 455 |  |  |         work = left ^ key[k++];
 | 
      
         | 456 |  |  |         t |= SP8[work & 0x3F];
 | 
      
         | 457 |  |  |         work >>>= 8;
 | 
      
         | 458 |  |  |         t |= SP6[work & 0x3F];
 | 
      
         | 459 |  |  |         work >>>= 8;
 | 
      
         | 460 |  |  |         t |= SP4[work & 0x3F];
 | 
      
         | 461 |  |  |         work >>>= 8;
 | 
      
         | 462 |  |  |         t |= SP2[work & 0x3F];
 | 
      
         | 463 |  |  |         right ^= t;
 | 
      
         | 464 |  |  |       }
 | 
      
         | 465 |  |  |     // The final permutation.
 | 
      
         | 466 |  |  |     right = (right << 31) | (right >>> 1);
 | 
      
         | 467 |  |  |     work = (left ^ right) & 0xAAAAAAAA;
 | 
      
         | 468 |  |  |     left ^= work;
 | 
      
         | 469 |  |  |     right ^= work;
 | 
      
         | 470 |  |  |     left = (left << 31) | (left >>> 1);
 | 
      
         | 471 |  |  |  
 | 
      
         | 472 |  |  |     work = ((left >>> 8) ^ right) & 0x00FF00FF;
 | 
      
         | 473 |  |  |     left ^= work << 8;
 | 
      
         | 474 |  |  |     right ^= work;
 | 
      
         | 475 |  |  |  
 | 
      
         | 476 |  |  |     work = ((left >>> 2) ^ right) & 0x33333333;
 | 
      
         | 477 |  |  |     left ^= work << 2;
 | 
      
         | 478 |  |  |     right ^= work;
 | 
      
         | 479 |  |  |  
 | 
      
         | 480 |  |  |     work = ((right >>> 16) ^ left) & 0x0000FFFF;
 | 
      
         | 481 |  |  |     right ^= work << 16;
 | 
      
         | 482 |  |  |     left ^= work;
 | 
      
         | 483 |  |  |  
 | 
      
         | 484 |  |  |     work = ((right >>> 4) ^ left) & 0x0F0F0F0F;
 | 
      
         | 485 |  |  |     right ^= work << 4;
 | 
      
         | 486 |  |  |     left ^= work;
 | 
      
         | 487 |  |  |  
 | 
      
         | 488 |  |  |     out[o++] = (byte)(right >>> 24);
 | 
      
         | 489 |  |  |     out[o++] = (byte)(right >>> 16);
 | 
      
         | 490 |  |  |     out[o++] = (byte)(right >>> 8);
 | 
      
         | 491 |  |  |     out[o++] = (byte) right;
 | 
      
         | 492 |  |  |     out[o++] = (byte)(left >>> 24);
 | 
      
         | 493 |  |  |     out[o++] = (byte)(left >>> 16);
 | 
      
         | 494 |  |  |     out[o++] = (byte)(left >>> 8);
 | 
      
         | 495 |  |  |     out[o  ] = (byte) left;
 | 
      
         | 496 |  |  |   }
 | 
      
         | 497 |  |  |  
 | 
      
         | 498 |  |  |   public Object clone()
 | 
      
         | 499 |  |  |   {
 | 
      
         | 500 |  |  |     return new DES();
 | 
      
         | 501 |  |  |   }
 | 
      
         | 502 |  |  |  
 | 
      
         | 503 |  |  |   public Iterator blockSizes()
 | 
      
         | 504 |  |  |   {
 | 
      
         | 505 |  |  |     return Collections.singleton(Integer.valueOf(BLOCK_SIZE)).iterator();
 | 
      
         | 506 |  |  |   }
 | 
      
         | 507 |  |  |  
 | 
      
         | 508 |  |  |   public Iterator keySizes()
 | 
      
         | 509 |  |  |   {
 | 
      
         | 510 |  |  |     return Collections.singleton(Integer.valueOf(KEY_SIZE)).iterator();
 | 
      
         | 511 |  |  |   }
 | 
      
         | 512 |  |  |  
 | 
      
         | 513 |  |  |   public Object makeKey(byte[] kb, int bs) throws InvalidKeyException
 | 
      
         | 514 |  |  |   {
 | 
      
         | 515 |  |  |     if (kb == null || kb.length != KEY_SIZE)
 | 
      
         | 516 |  |  |       throw new InvalidKeyException("DES keys must be 8 bytes long");
 | 
      
         | 517 |  |  |  
 | 
      
         | 518 |  |  |     if (Properties.checkForWeakKeys()
 | 
      
         | 519 |  |  |         && (isWeak(kb) || isSemiWeak(kb) || isPossibleWeak(kb)))
 | 
      
         | 520 |  |  |       throw new WeakKeyException();
 | 
      
         | 521 |  |  |  
 | 
      
         | 522 |  |  |     int i, j, l, m, n;
 | 
      
         | 523 |  |  |     long pc1m = 0, pcr = 0;
 | 
      
         | 524 |  |  |  
 | 
      
         | 525 |  |  |     for (i = 0; i < 56; i++)
 | 
      
         | 526 |  |  |       {
 | 
      
         | 527 |  |  |         l = PC1[i];
 | 
      
         | 528 |  |  |         pc1m |= ((kb[l >>> 3] & (0x80 >>> (l & 7))) != 0) ? (1L << (55 - i))
 | 
      
         | 529 |  |  |                                                           : 0;
 | 
      
         | 530 |  |  |       }
 | 
      
         | 531 |  |  |     Context ctx = new Context();
 | 
      
         | 532 |  |  |     // Encryption key first.
 | 
      
         | 533 |  |  |     for (i = 0; i < 16; i++)
 | 
      
         | 534 |  |  |       {
 | 
      
         | 535 |  |  |         pcr = 0;
 | 
      
         | 536 |  |  |         m = i << 1;
 | 
      
         | 537 |  |  |         n = m + 1;
 | 
      
         | 538 |  |  |         for (j = 0; j < 28; j++)
 | 
      
         | 539 |  |  |           {
 | 
      
         | 540 |  |  |             l = j + ROTARS[i];
 | 
      
         | 541 |  |  |             if (l < 28)
 | 
      
         | 542 |  |  |               pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
 | 
      
         | 543 |  |  |             else
 | 
      
         | 544 |  |  |               pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
 | 
      
         | 545 |  |  |                                                            : 0;
 | 
      
         | 546 |  |  |           }
 | 
      
         | 547 |  |  |         for (j = 28; j < 56; j++)
 | 
      
         | 548 |  |  |           {
 | 
      
         | 549 |  |  |             l = j + ROTARS[i];
 | 
      
         | 550 |  |  |             if (l < 56)
 | 
      
         | 551 |  |  |               pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
 | 
      
         | 552 |  |  |             else
 | 
      
         | 553 |  |  |               pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
 | 
      
         | 554 |  |  |                                                            : 0;
 | 
      
         | 555 |  |  |           }
 | 
      
         | 556 |  |  |         for (j = 0; j < 24; j++)
 | 
      
         | 557 |  |  |           {
 | 
      
         | 558 |  |  |             if ((pcr & 1L << (55 - PC2[j])) != 0)
 | 
      
         | 559 |  |  |               ctx.ek[m] |= 1 << (23 - j);
 | 
      
         | 560 |  |  |             if ((pcr & 1L << (55 - PC2[j + 24])) != 0)
 | 
      
         | 561 |  |  |               ctx.ek[n] |= 1 << (23 - j);
 | 
      
         | 562 |  |  |           }
 | 
      
         | 563 |  |  |       }
 | 
      
         | 564 |  |  |     // The decryption key is the same, but in reversed order.
 | 
      
         | 565 |  |  |     for (i = 0; i < Context.EXPANDED_KEY_SIZE; i += 2)
 | 
      
         | 566 |  |  |       {
 | 
      
         | 567 |  |  |         ctx.dk[30 - i] = ctx.ek[i];
 | 
      
         | 568 |  |  |         ctx.dk[31 - i] = ctx.ek[i + 1];
 | 
      
         | 569 |  |  |       }
 | 
      
         | 570 |  |  |     // "Cook" the keys.
 | 
      
         | 571 |  |  |     for (i = 0; i < 32; i += 2)
 | 
      
         | 572 |  |  |       {
 | 
      
         | 573 |  |  |         int x, y;
 | 
      
         | 574 |  |  |         x = ctx.ek[i];
 | 
      
         | 575 |  |  |         y = ctx.ek[i + 1];
 | 
      
         | 576 |  |  |         ctx.ek[i    ] = ((x & 0x00FC0000)  <<  6)
 | 
      
         | 577 |  |  |                       | ((x & 0x00000FC0)  << 10)
 | 
      
         | 578 |  |  |                       | ((y & 0x00FC0000) >>> 10)
 | 
      
         | 579 |  |  |                       | ((y & 0x00000FC0) >>>  6);
 | 
      
         | 580 |  |  |         ctx.ek[i + 1] = ((x & 0x0003F000)  << 12)
 | 
      
         | 581 |  |  |                       | ((x & 0x0000003F)  << 16)
 | 
      
         | 582 |  |  |                       | ((y & 0x0003F000) >>>  4)
 | 
      
         | 583 |  |  |                       |  (y & 0x0000003F);
 | 
      
         | 584 |  |  |         x = ctx.dk[i];
 | 
      
         | 585 |  |  |         y = ctx.dk[i + 1];
 | 
      
         | 586 |  |  |         ctx.dk[i    ] = ((x & 0x00FC0000)  <<  6)
 | 
      
         | 587 |  |  |                       | ((x & 0x00000FC0)  << 10)
 | 
      
         | 588 |  |  |                       | ((y & 0x00FC0000) >>> 10)
 | 
      
         | 589 |  |  |                       | ((y & 0x00000FC0) >>>  6);
 | 
      
         | 590 |  |  |         ctx.dk[i + 1] = ((x & 0x0003F000)  << 12)
 | 
      
         | 591 |  |  |                       | ((x & 0x0000003F)  << 16)
 | 
      
         | 592 |  |  |                       | ((y & 0x0003F000) >>>  4)
 | 
      
         | 593 |  |  |                       |  (y & 0x0000003F);
 | 
      
         | 594 |  |  |       }
 | 
      
         | 595 |  |  |     return ctx;
 | 
      
         | 596 |  |  |   }
 | 
      
         | 597 |  |  |  
 | 
      
         | 598 |  |  |   public void encrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
 | 
      
         | 599 |  |  |   {
 | 
      
         | 600 |  |  |     desFunc(in, i, out, o, ((Context) K).ek);
 | 
      
         | 601 |  |  |   }
 | 
      
         | 602 |  |  |  
 | 
      
         | 603 |  |  |   public void decrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
 | 
      
         | 604 |  |  |   {
 | 
      
         | 605 |  |  |     desFunc(in, i, out, o, ((Context) K).dk);
 | 
      
         | 606 |  |  |   }
 | 
      
         | 607 |  |  |  
 | 
      
         | 608 |  |  |   /**
 | 
      
         | 609 |  |  |    * Simple wrapper class around the session keys. Package-private so TripleDES
 | 
      
         | 610 |  |  |    * can see it.
 | 
      
         | 611 |  |  |    */
 | 
      
         | 612 |  |  |   final class Context
 | 
      
         | 613 |  |  |   {
 | 
      
         | 614 |  |  |     private static final int EXPANDED_KEY_SIZE = 32;
 | 
      
         | 615 |  |  |  
 | 
      
         | 616 |  |  |     /** The encryption key. */
 | 
      
         | 617 |  |  |     int[] ek;
 | 
      
         | 618 |  |  |  
 | 
      
         | 619 |  |  |     /** The decryption key. */
 | 
      
         | 620 |  |  |     int[] dk;
 | 
      
         | 621 |  |  |  
 | 
      
         | 622 |  |  |     /** Default 0-arguments constructor. */
 | 
      
         | 623 |  |  |     Context()
 | 
      
         | 624 |  |  |     {
 | 
      
         | 625 |  |  |       ek = new int[EXPANDED_KEY_SIZE];
 | 
      
         | 626 |  |  |       dk = new int[EXPANDED_KEY_SIZE];
 | 
      
         | 627 |  |  |     }
 | 
      
         | 628 |  |  |  
 | 
      
         | 629 |  |  |     byte[] getEncryptionKeyBytes()
 | 
      
         | 630 |  |  |     {
 | 
      
         | 631 |  |  |       return toByteArray(ek);
 | 
      
         | 632 |  |  |     }
 | 
      
         | 633 |  |  |  
 | 
      
         | 634 |  |  |     byte[] getDecryptionKeyBytes()
 | 
      
         | 635 |  |  |     {
 | 
      
         | 636 |  |  |       return toByteArray(dk);
 | 
      
         | 637 |  |  |     }
 | 
      
         | 638 |  |  |  
 | 
      
         | 639 |  |  |     byte[] toByteArray(int[] k)
 | 
      
         | 640 |  |  |     {
 | 
      
         | 641 |  |  |       byte[] result = new byte[4 * k.length];
 | 
      
         | 642 |  |  |       for (int i = 0, j = 0; i < k.length; i++)
 | 
      
         | 643 |  |  |         {
 | 
      
         | 644 |  |  |           result[j++] = (byte)(k[i] >>> 24);
 | 
      
         | 645 |  |  |           result[j++] = (byte)(k[i] >>> 16);
 | 
      
         | 646 |  |  |           result[j++] = (byte)(k[i] >>> 8);
 | 
      
         | 647 |  |  |           result[j++] = (byte) k[i];
 | 
      
         | 648 |  |  |         }
 | 
      
         | 649 |  |  |       return result;
 | 
      
         | 650 |  |  |     }
 | 
      
         | 651 |  |  |   }
 | 
      
         | 652 |  |  | }
 |