MapleAESOFB.java
上传用户:gwt600
上传日期:2021-06-03
资源大小:704k
文件大小:18k
源码类别:

游戏

开发平台:

Java

  1. /*
  2. This file is part of the OdinMS Maple Story Server
  3.     Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc> 
  4.                        Matthias Butz <matze@odinms.de>
  5.                        Jan Christian Meyer <vimes@odinms.de>
  6.     This program is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU Affero General Public License version 3
  8.     as published by the Free Software Foundation. You may not use, modify
  9.     or distribute this program under any other version of the
  10.     GNU Affero General Public License.
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU Affero General Public License for more details.
  15.     You should have received a copy of the GNU Affero General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. package net.sf.odinms.tools;
  19. import java.security.InvalidKeyException;
  20. import java.security.NoSuchAlgorithmException;
  21. import javax.crypto.BadPaddingException;
  22. import javax.crypto.Cipher;
  23. import javax.crypto.IllegalBlockSizeException;
  24. import javax.crypto.NoSuchPaddingException;
  25. import javax.crypto.spec.SecretKeySpec;
  26. import org.slf4j.LoggerFactory;
  27. import org.slf4j.Logger;
  28. /**
  29.  * Provides a class for encrypting MapleStory packets with AES OFB encryption.
  30.  * 
  31.  * @author Frz
  32.  * @version 1.0
  33.  * @since Revision 320
  34.  */
  35. public class MapleAESOFB {
  36. private byte iv[];
  37. private Cipher cipher;
  38. private short mapleVersion;
  39.         /* VANA */
  40.           private static final byte[] funnyBytes = new byte[] {(byte)0xEC,(byte)0x3F, (byte)0x77, (byte)0xA4, (byte)0x45, (byte)0xD0, (byte)0x71, (byte)0xBF, (byte)0xB7, (byte)0x98, (byte)0x20, (byte)0xFC,
  41.           (byte)0x4B, (byte)0xE9, (byte)0xB3, (byte)0xE1, (byte)0x5C, (byte)0x22, (byte)0xF7, (byte)0x0C, (byte)0x44, (byte)0x1B, (byte)0x81, (byte)0xBD, (byte)0x63, (byte)0x8D, (byte)0xD4, (byte)0xC3,
  42.           (byte)0xF2, (byte)0x10, (byte)0x19, (byte)0xE0, (byte)0xFB, (byte)0xA1, (byte)0x6E, (byte)0x66, (byte)0xEA, (byte)0xAE, (byte)0xD6, (byte)0xCE, (byte)0x06, (byte)0x18, (byte)0x4E, (byte)0xEB,
  43.           (byte)0x78, (byte)0x95, (byte)0xDB, (byte)0xBA, (byte)0xB6, (byte)0x42, (byte)0x7A, (byte)0x2A, (byte)0x83, (byte)0x0B, (byte)0x54, (byte)0x67, (byte)0x6D, (byte)0xE8, (byte)0x65, (byte)0xE7,
  44.           (byte)0x2F, (byte)0x07, (byte)0xF3, (byte)0xAA, (byte)0x27, (byte)0x7B, (byte)0x85, (byte)0xB0, (byte)0x26, (byte)0xFD, (byte)0x8B, (byte)0xA9, (byte)0xFA, (byte)0xBE, (byte)0xA8, (byte)0xD7,
  45.           (byte)0xCB, (byte)0xCC, (byte)0x92, (byte)0xDA, (byte)0xF9, (byte)0x93, (byte)0x60, (byte)0x2D, (byte)0xDD, (byte)0xD2, (byte)0xA2, (byte)0x9B, (byte)0x39, (byte)0x5F, (byte)0x82, (byte)0x21,
  46.           (byte)0x4C, (byte)0x69, (byte)0xF8, (byte)0x31, (byte)0x87, (byte)0xEE, (byte)0x8E, (byte)0xAD, (byte)0x8C, (byte)0x6A, (byte)0xBC, (byte)0xB5, (byte)0x6B, (byte)0x59, (byte)0x13, (byte)0xF1,
  47.           (byte)0x04, (byte)0x00, (byte)0xF6, (byte)0x5A, (byte)0x35, (byte)0x79, (byte)0x48, (byte)0x8F, (byte)0x15, (byte)0xCD, (byte)0x97, (byte)0x57, (byte)0x12, (byte)0x3E, (byte)0x37, (byte)0xFF,
  48.           (byte)0x9D, (byte)0x4F, (byte)0x51, (byte)0xF5, (byte)0xA3, (byte)0x70, (byte)0xBB, (byte)0x14, (byte)0x75, (byte)0xC2, (byte)0xB8, (byte)0x72, (byte)0xC0, (byte)0xED, (byte)0x7D, (byte)0x68,
  49.           (byte)0xC9, (byte)0x2E, (byte)0x0D, (byte)0x62, (byte)0x46, (byte)0x17, (byte)0x11, (byte)0x4D, (byte)0x6C, (byte)0xC4, (byte)0x7E, (byte)0x53, (byte)0xC1, (byte)0x25, (byte)0xC7, (byte)0x9A,
  50.           (byte)0x1C, (byte)0x88, (byte)0x58, (byte)0x2C, (byte)0x89, (byte)0xDC, (byte)0x02, (byte)0x64, (byte)0x40, (byte)0x01, (byte)0x5D, (byte)0x38, (byte)0xA5, (byte)0xE2, (byte)0xAF, (byte)0x55,
  51.           (byte)0xD5, (byte)0xEF, (byte)0x1A, (byte)0x7C, (byte)0xA7, (byte)0x5B, (byte)0xA6, (byte)0x6F, (byte)0x86, (byte)0x9F, (byte)0x73, (byte)0xE6, (byte)0x0A, (byte)0xDE, (byte)0x2B, (byte)0x99,
  52.           (byte)0x4A, (byte)0x47, (byte)0x9C, (byte)0xDF, (byte)0x09, (byte)0x76, (byte)0x9E, (byte)0x30, (byte)0x0E, (byte)0xE4, (byte)0xB2, (byte)0x94, (byte)0xA0, (byte)0x3B, (byte)0x34, (byte)0x1D,
  53.           (byte)0x28, (byte)0x0F, (byte)0x36, (byte)0xE3, (byte)0x23, (byte)0xB4, (byte)0x03, (byte)0xD8, (byte)0x90, (byte)0xC8, (byte)0x3C, (byte)0xFE, (byte)0x5E, (byte)0x32, (byte)0x24, (byte)0x50,
  54.           (byte)0x1F, (byte)0x3A, (byte)0x43, (byte)0x8A, (byte)0x96, (byte)0x41, (byte)0x74, (byte)0xAC, (byte)0x52, (byte)0x33, (byte)0xF0, (byte)0xD9, (byte)0x29, (byte)0x80, (byte)0xB1, (byte)0x16,
  55.           (byte)0xD3, (byte)0xAB, (byte)0x91, (byte)0xB9, (byte)0x84, (byte)0x7F, (byte)0x61, (byte)0x1E, (byte)0xCF, (byte)0xC5, (byte)0xD1, (byte)0x56, (byte)0x3D, (byte)0xCA, (byte)0xF4, (byte)0x05,
  56.           (byte)0xC6, (byte)0xE5, (byte)0x08, (byte)0x49};
  57.           
  58. /* ORIGINAL
  59.          private static final byte[] funnyBytes2 = new byte[] { (byte) 0xEC, 0x3F, 0x77, (byte) 0xA4, 0x45, (byte) 0xD0,
  60. 0x71, (byte) 0xBF, (byte) 0xB7, (byte) 0x98, 0x20, (byte) 0xFC, 0x4B, (byte) 0xE9, (byte) 0xB3, (byte) 0xE1,
  61. 0x5C, 0x22, (byte) 0xF7, 0x0C, 0x44, 0x1B, (byte) 0x81, (byte) 0xBD, 0x63, (byte) 0x8D, (byte) 0xD4,
  62. (byte) 0xC3, (byte) 0xF2, 0x10, 0x19, (byte) 0xE0, (byte) 0xFB, (byte) 0xA1, 0x6E, 0x66, (byte) 0xEA,
  63. (byte) 0xAE, (byte) 0xD6, (byte) 0xCE, 0x06, 0x18, 0x4E, (byte) 0xEB, 0x78, (byte) 0x95, (byte) 0xDB,
  64. (byte) 0xBA, (byte) 0xB6, 0x42, 0x7A, 0x2A, (byte) 0x83, 0x0B, 0x54, 0x67, 0x6D, (byte) 0xE8, 0x65,
  65. (byte) 0xE7, 0x2F, 0x07, (byte) 0xF3, (byte) 0xAA, 0x27, 0x7B, (byte) 0x85, (byte) 0xB0, 0x26, (byte) 0xFD,
  66. (byte) 0x8B, (byte) 0xA9, (byte) 0xFA, (byte) 0xBE, (byte) 0xA8, (byte) 0xD7, (byte) 0xCB, (byte) 0xCC,
  67. (byte) 0x92, (byte) 0xDA, (byte) 0xF9, (byte) 0x93, 0x60, 0x2D, (byte) 0xDD, (byte) 0xD2, (byte) 0xA2,
  68. (byte) 0x9B, 0x39, 0x5F, (byte) 0x82, 0x21, 0x4C, 0x69, (byte) 0xF8, 0x31, (byte) 0x87, (byte) 0xEE,
  69. (byte) 0x8E, (byte) 0xAD, (byte) 0x8C, 0x6A, (byte) 0xBC, (byte) 0xB5, 0x6B, 0x59, 0x13, (byte) 0xF1, 0x04,
  70. 0x00, (byte) 0xF6, 0x5A, 0x35, 0x79, 0x48, (byte) 0x8F, 0x15, (byte) 0xCD, (byte) 0x97, 0x57, 0x12, 0x3E, 0x37,
  71. (byte) 0xFF, (byte) 0x9D, 0x4F, 0x51, (byte) 0xF5, (byte) 0xA3, 0x70, (byte) 0xBB, 0x14, 0x75, (byte) 0xC2,
  72. (byte) 0xB8, 0x72, (byte) 0xC0, (byte) 0xED, 0x7D, 0x68, (byte) 0xC9, 0x2E, 0x0D, 0x62, 0x46, 0x17, 0x11, 0x4D,
  73. 0x6C, (byte) 0xC4, 0x7E, 0x53, (byte) 0xC1, 0x25, (byte) 0xC7, (byte) 0x9A, 0x1C, (byte) 0x88, 0x58, 0x2C,
  74. (byte) 0x89, (byte) 0xDC, 0x02, 0x64, 0x40, 0x01, 0x5D, 0x38, (byte) 0xA5, (byte) 0xE2, (byte) 0xAF, 0x55,
  75. (byte) 0xD5, (byte) 0xEF, 0x1A, 0x7C, (byte) 0xA7, 0x5B, (byte) 0xA6, 0x6F, (byte) 0x86, (byte) 0x9F, 0x73,
  76. (byte) 0xE6, 0x0A, (byte) 0xDE, 0x2B, (byte) 0x99, 0x4A, 0x47, (byte) 0x9C, (byte) 0xDF, 0x09, 0x76,
  77. (byte) 0x9E, 0x30, 0x0E, (byte) 0xE4, (byte) 0xB2, (byte) 0x94, (byte) 0xA0, 0x3B, 0x34, 0x1D, 0x28, 0x0F,
  78. 0x36, (byte) 0xE3, 0x23, (byte) 0xB4, 0x03, (byte) 0xD8, (byte) 0x90, (byte) 0xC8, 0x3C, (byte) 0xFE, 0x5E,
  79. 0x32, 0x24, 0x50, 0x1F, 0x3A, 0x43, (byte) 0x8A, (byte) 0x96, 0x41, 0x74, (byte) 0xAC, 0x52, 0x33, (byte) 0xF0,
  80. (byte) 0xD9, 0x29, (byte) 0x80, (byte) 0xB1, 0x16, (byte) 0xD3, (byte) 0xAB, (byte) 0x91, (byte) 0xB9,
  81. (byte) 0x84, 0x7F, 0x61, 0x1E, (byte) 0xCF, (byte) 0xC5, (byte) 0xD1, 0x56, 0x3D, (byte) 0xCA, (byte) 0xF4,
  82. 0x05, (byte) 0xC6, (byte) 0xE5, 0x08, 0x49, 0x4F, 0x64, 0x69, 0x6E, 0x4D, 0x53, 0x7E, 0x46, 0x72, 0x7A };*/
  83. private Logger log = LoggerFactory.getLogger(MapleAESOFB.class);
  84. /**
  85.  * Class constructor - Creates an instance of the MapleStory encryption
  86.  * cipher.
  87.  * 
  88.  * @param key The 256 bit AES key to use.
  89.  * @param iv The 4-byte IV to use.
  90.  */
  91. public MapleAESOFB(byte key[], byte iv[], short mapleVersion) {
  92. SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
  93. try {
  94. cipher = Cipher.getInstance("AES");
  95. } catch (NoSuchAlgorithmException e) {
  96. log.error("ERROR", e);
  97. } catch (NoSuchPaddingException e) {
  98. log.error("ERROR", e);
  99. }
  100. try {
  101. cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
  102. } catch (InvalidKeyException e) {
  103. log
  104. .error("Error initalizing the encryption cipher.  Make sure you're using the Unlimited Strength cryptography jar files.");
  105. }
  106. this.setIv(iv);
  107. this.mapleVersion = (short) (((mapleVersion >> 8) & 0xFF) | ((mapleVersion << 8) & 0xFF00));
  108. }
  109. /**
  110.  * Sets the IV of this instance.
  111.  * 
  112.  * @param iv The new IV.
  113.  */
  114. private void setIv(byte[] iv) {
  115. this.iv = iv;
  116. }
  117. /**
  118.  * For debugging/testing purposes only.
  119.  * 
  120.  * @return The IV.
  121.  */
  122. public byte[] getIv() {
  123. return this.iv;
  124. }
  125. /**
  126.  * Encrypts <code>data</code> and generates a new IV.
  127.  * 
  128.  * @param data The bytes to encrypt.
  129.  * @return The encrypted bytes.
  130.  */
  131. public byte[] crypt(byte[] data) {
  132. int remaining = data.length;
  133. int llength = 0x5B0;
  134. int start = 0;
  135. while (remaining > 0) {
  136. byte[] myIv = BitTools.multiplyBytes(this.iv, 4, 4);
  137. if (remaining < llength) {
  138. llength = remaining;
  139. }
  140. for (int x = start; x < (start + llength); x++) {
  141. if ((x - start) % myIv.length == 0) {
  142. try {
  143. byte[] newIv = cipher.doFinal(myIv);
  144. for (int j = 0; j < myIv.length; j++) {
  145. myIv[j] = newIv[j];
  146. }
  147. // System.out
  148. // .println("Iv is now " + HexTool.toString(this.iv));
  149. } catch (IllegalBlockSizeException e) {
  150. e.printStackTrace();
  151. } catch (BadPaddingException e) {
  152. e.printStackTrace();
  153. }
  154. }
  155. data[x] ^= myIv[(x - start) % myIv.length];
  156. }
  157. start += llength;
  158. remaining -= llength;
  159. llength = 0x5B4;
  160. }
  161. updateIv();
  162. return data;
  163. }
  164. /**
  165.  * Generates a new IV.
  166.  */
  167. private void updateIv() {
  168. this.iv = getNewIv(this.iv);
  169. }
  170. /**
  171.  * Generates a packet header for a packet that is <code>length</code>
  172.  * long.
  173.  * 
  174.  * @param length How long the packet that this header is for is.
  175.  * @return The header.
  176.  */
  177. public byte[] getPacketHeader(int length) {
  178. int iiv = (iv[3]) & 0xFF;
  179. iiv |= (iv[2] << 8) & 0xFF00;
  180. iiv ^= mapleVersion;
  181. int mlength = ((length << 8) & 0xFF00) | (length >>> 8);
  182. int xoredIv = iiv ^ mlength;
  183. byte[] ret = new byte[4];
  184. ret[0] = (byte) ((iiv >>> 8) & 0xFF);
  185. ret[1] = (byte) (iiv & 0xFF);
  186. ret[2] = (byte) ((xoredIv >>> 8) & 0xFF);
  187. ret[3] = (byte) (xoredIv & 0xFF);
  188. return ret;
  189. }
  190. /**
  191.  * Gets the packet length from a header.
  192.  * 
  193.  * @param packetHeader The header as an integer.
  194.  * @return The length of the packet.
  195.  */
  196. public static int getPacketLength(int packetHeader) {
  197. int packetLength = ((packetHeader >>> 16) ^ (packetHeader & 0xFFFF));
  198. packetLength = ((packetLength << 8) & 0xFF00) | ((packetLength >>> 8) & 0xFF); // fix
  199. // endianness
  200. return packetLength;
  201. }
  202. /**
  203.  * Check the packet to make sure it has a header.
  204.  * 
  205.  * @param packet The packet to check.
  206.  * @return <code>True</code> if the packet has a correct header,
  207.  *         <code>false</code> otherwise.
  208.  */
  209. public boolean checkPacket(byte[] packet) {
  210. return ((((packet[0] ^ iv[2]) & 0xFF) == ((mapleVersion >> 8) & 0xFF)) && (((packet[1] ^ iv[3]) & 0xFF) == (mapleVersion & 0xFF)));
  211. }
  212. /**
  213.  * Check the header for validity.
  214.  * 
  215.  * @param packetHeader The packet header to check.
  216.  * @return <code>True</code> if the header is correct, <code>false</code>
  217.  *         otherwise.
  218.  */
  219. public boolean checkPacket(int packetHeader) {
  220. byte packetHeaderBuf[] = new byte[2];
  221. packetHeaderBuf[0] = (byte) ((packetHeader >> 24) & 0xFF);
  222. packetHeaderBuf[1] = (byte) ((packetHeader >> 16) & 0xFF);
  223. return checkPacket(packetHeaderBuf);
  224. }
  225. /**
  226.  * Gets a new IV from <code>oldIv</code>
  227.  * 
  228.  * @param oldIv The old IV to get a new IV from.
  229.  * @return The new IV.
  230.  */
  231. public static byte[] getNewIv(byte oldIv[]) {
  232. byte[] in = { (byte) 0xf2, 0x53, (byte) 0x50, (byte) 0xc6 }; // magic
  233. // ;)
  234. for (int x = 0; x < 4; x++) {
  235. funnyShit(oldIv[x], in);
  236.                         //funnyRamon(oldIv[x], in);
  237. // System.out.println(HexTool.toString(in));
  238. }
  239. return in;
  240. }
  241. /**
  242.  * Returns the IV of this instance as a string.
  243.  */
  244. @Override
  245. public String toString() {
  246. return "IV: " + HexTool.toString(this.iv);
  247. }
  248. /**
  249.  * Does funny stuff. <code>this.OldIV</code> must not equal
  250.  * <code>in</code> Modifies <code>in</code> and returns it for
  251.  * convenience.
  252.  * 
  253.  * @param inputByte The byte to apply the funny stuff to.
  254.  * @param in Something needed for all this to occur.
  255.  * @return The modified version of <code>in</code>.
  256.  */
  257. public static byte[] funnyShit(byte inputByte, byte[] in) {
  258. byte elina = in[1];
  259. byte anna = inputByte;
  260. byte moritz = funnyBytes[(int) elina & 0xFF];
  261. moritz -= inputByte;
  262. in[0] += moritz;
  263. moritz = in[2];
  264. moritz ^= funnyBytes[(int) anna & 0xFF];
  265. elina -= (int) moritz & 0xFF;
  266. in[1] = elina;
  267. elina = in[3];
  268. moritz = elina;
  269. elina -= (int) in[0] & 0xFF;
  270. moritz = funnyBytes[(int) moritz & 0xFF];
  271. moritz += inputByte;
  272. moritz ^= in[2];
  273. in[2] = moritz;
  274. elina += (int) funnyBytes[(int) anna & 0xFF] & 0xFF;
  275. in[3] = elina;
  276. int merry = ((int) in[0]) & 0xFF;
  277. merry |= (in[1] << 8) & 0xFF00;
  278. merry |= (in[2] << 16) & 0xFF0000;
  279. merry |= (in[3] << 24) & 0xFF000000;
  280. int ret_value = merry;
  281. ret_value = ret_value >>> 0x1d;
  282. merry = merry << 3;
  283. ret_value = ret_value | merry;
  284. in[0] = (byte) (ret_value & 0xFF);
  285. in[1] = (byte) ((ret_value >> 8) & 0xFF);
  286. in[2] = (byte) ((ret_value >> 16) & 0xFF);
  287. in[3] = (byte) ((ret_value >> 24) & 0xFF);
  288. return in;
  289. }
  290.         
  291.         public static byte[] funnyRamon(byte inputByte, byte[] in) {
  292.           byte[] rammyByte = new byte[] {(byte)0xEC,(byte)0x3F, (byte)0x77, (byte)0xA4, (byte)0x45, (byte)0xD0, (byte)0x71, (byte)0xBF, (byte)0xB7, (byte)0x98, (byte)0x20, (byte)0xFC,
  293.           (byte)0x4B, (byte)0xE9, (byte)0xB3, (byte)0xE1, (byte)0x5C, (byte)0x22, (byte)0xF7, (byte)0x0C, (byte)0x44, (byte)0x1B, (byte)0x81, (byte)0xBD, (byte)0x63, (byte)0x8D, (byte)0xD4, (byte)0xC3,
  294.           (byte)0xF2, (byte)0x10, (byte)0x19, (byte)0xE0, (byte)0xFB, (byte)0xA1, (byte)0x6E, (byte)0x66, (byte)0xEA, (byte)0xAE, (byte)0xD6, (byte)0xCE, (byte)0x06, (byte)0x18, (byte)0x4E, (byte)0xEB,
  295.           (byte)0x78, (byte)0x95, (byte)0xDB, (byte)0xBA, (byte)0xB6, (byte)0x42, (byte)0x7A, (byte)0x2A, (byte)0x83, (byte)0x0B, (byte)0x54, (byte)0x67, (byte)0x6D, (byte)0xE8, (byte)0x65, (byte)0xE7,
  296.           (byte)0x2F, (byte)0x07, (byte)0xF3, (byte)0xAA, (byte)0x27, (byte)0x7B, (byte)0x85, (byte)0xB0, (byte)0x26, (byte)0xFD, (byte)0x8B, (byte)0xA9, (byte)0xFA, (byte)0xBE, (byte)0xA8, (byte)0xD7,
  297.           (byte)0xCB, (byte)0xCC, (byte)0x92, (byte)0xDA, (byte)0xF9, (byte)0x93, (byte)0x60, (byte)0x2D, (byte)0xDD, (byte)0xD2, (byte)0xA2, (byte)0x9B, (byte)0x39, (byte)0x5F, (byte)0x82, (byte)0x21,
  298.           (byte)0x4C, (byte)0x69, (byte)0xF8, (byte)0x31, (byte)0x87, (byte)0xEE, (byte)0x8E, (byte)0xAD, (byte)0x8C, (byte)0x6A, (byte)0xBC, (byte)0xB5, (byte)0x6B, (byte)0x59, (byte)0x13, (byte)0xF1,
  299.           (byte)0x04, (byte)0x00, (byte)0xF6, (byte)0x5A, (byte)0x35, (byte)0x79, (byte)0x48, (byte)0x8F, (byte)0x15, (byte)0xCD, (byte)0x97, (byte)0x57, (byte)0x12, (byte)0x3E, (byte)0x37, (byte)0xFF,
  300.           (byte)0x9D, (byte)0x4F, (byte)0x51, (byte)0xF5, (byte)0xA3, (byte)0x70, (byte)0xBB, (byte)0x14, (byte)0x75, (byte)0xC2, (byte)0xB8, (byte)0x72, (byte)0xC0, (byte)0xED, (byte)0x7D, (byte)0x68,
  301.           (byte)0xC9, (byte)0x2E, (byte)0x0D, (byte)0x62, (byte)0x46, (byte)0x17, (byte)0x11, (byte)0x4D, (byte)0x6C, (byte)0xC4, (byte)0x7E, (byte)0x53, (byte)0xC1, (byte)0x25, (byte)0xC7, (byte)0x9A,
  302.           (byte)0x1C, (byte)0x88, (byte)0x58, (byte)0x2C, (byte)0x89, (byte)0xDC, (byte)0x02, (byte)0x64, (byte)0x40, (byte)0x01, (byte)0x5D, (byte)0x38, (byte)0xA5, (byte)0xE2, (byte)0xAF, (byte)0x55,
  303.           (byte)0xD5, (byte)0xEF, (byte)0x1A, (byte)0x7C, (byte)0xA7, (byte)0x5B, (byte)0xA6, (byte)0x6F, (byte)0x86, (byte)0x9F, (byte)0x73, (byte)0xE6, (byte)0x0A, (byte)0xDE, (byte)0x2B, (byte)0x99,
  304.           (byte)0x4A, (byte)0x47, (byte)0x9C, (byte)0xDF, (byte)0x09, (byte)0x76, (byte)0x9E, (byte)0x30, (byte)0x0E, (byte)0xE4, (byte)0xB2, (byte)0x94, (byte)0xA0, (byte)0x3B, (byte)0x34, (byte)0x1D,
  305.           (byte)0x28, (byte)0x0F, (byte)0x36, (byte)0xE3, (byte)0x23, (byte)0xB4, (byte)0x03, (byte)0xD8, (byte)0x90, (byte)0xC8, (byte)0x3C, (byte)0xFE, (byte)0x5E, (byte)0x32, (byte)0x24, (byte)0x50,
  306.           (byte)0x1F, (byte)0x3A, (byte)0x43, (byte)0x8A, (byte)0x96, (byte)0x41, (byte)0x74, (byte)0xAC, (byte)0x52, (byte)0x33, (byte)0xF0, (byte)0xD9, (byte)0x29, (byte)0x80, (byte)0xB1, (byte)0x16,
  307.           (byte)0xD3, (byte)0xAB, (byte)0x91, (byte)0xB9, (byte)0x84, (byte)0x7F, (byte)0x61, (byte)0x1E, (byte)0xCF, (byte)0xC5, (byte)0xD1, (byte)0x56, (byte)0x3D, (byte)0xCA, (byte)0xF4, (byte)0x05,
  308.           (byte)0xC6, (byte)0xE5, (byte)0x08, (byte)0x49};
  309.           
  310.          //for (int i=0; i<4; i++) {
  311.                   byte a = in[1];
  312.                   byte b =  a;
  313.                   b = rammyByte[b];
  314.                   b -= inputByte;
  315.                   in[0] += b;
  316.                   b = in[2];
  317.                   b = ((byte)(b ^ rammyByte[inputByte]));
  318.                   a -= b;
  319.                   in[1] = a;
  320.                   a = in[3];
  321.                   b = a;
  322.                   a -= in[0];
  323.                   b = rammyByte[b];
  324.                   b += inputByte;
  325.                   b = ((byte)(b ^ in[2]));
  326.                   in[2] = b;
  327.                   a += rammyByte[inputByte];
  328.                   in[3] = a;
  329.                   int c = 0, d = 0;
  330.                   for (int j=0; j<4; j++) {
  331.                           c = in[0] + in[1]*0x100 + in[2]*0x100*0x100 + in[3]*0x100*0x100*0x100;
  332.                           d = c;
  333.                   }
  334.                   c = c >> 0x1D;
  335.                   d = d << 0x03;
  336.                   c = c | d;
  337.                   in[0] = ((byte)(c%0x100));
  338.                   c = c / 0x100;
  339.                   in[1] = ((byte)(c%0x100));
  340.                   c = c / 0x100;
  341.                   in[2] = ((byte)(c%0x100));
  342.                   in[3] = ((byte)(c / 0x100));
  343.           //}
  344.           //for (int i=0; i<4; i++)
  345.                   //inputByte[i] = in[i];
  346.           return in;
  347.         }
  348. }