0001: /* $Id: CAST5.java,v 1.1 2004/01/19 02:03:50 rgrimm Exp $
0002: *
0003: * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
0004: * All rights reserved.
0005: *
0006: * Use, modification, copying and distribution of this software is subject
0007: * the terms and conditions of the Cryptix General Licence. You should have
0008: * received a copy of the Cryptix General Licence along with this library;
0009: * if not, you can download a copy from http://www.cryptix.org/ .
0010: */
0011:
0012: package cryptix.jce.provider.cipher;
0013:
0014: import java.security.InvalidKeyException;
0015: import java.security.Key;
0016:
0017: /**
0018: * CAST5 (a.k.a. CAST-128) in Java, as per RFC 2144.
0019: * <p>
0020: * The author, Carlisle Adams (the CA in CAST, ST standing for Stafford
0021: * Tavares) describes CAST5 as:
0022: * <p>
0023: * <blockquote>
0024: * "...a DES-like Substitution-Permutation Network (SPN) cryptosystem
0025: * which appears to have good resistance to differential cryptanalysis,
0026: * linear cryptanalysis, and related-key cryptanalysis. This cipher
0027: * also possesses a number of other desirable cryptographic properties,
0028: * including avalanche, Strict Avalanche Criterion (SAC), Bit
0029: * Independence Criterion (BIC), no complementation property, and an
0030: * absence of weak and semi-weak keys."
0031: * </blockquote>
0032: * <p>
0033: * CAST5 is a symmetric block cipher with a block-size of 8 bytes and
0034: * a variable key-size of up to 128 bits. Its authors and their employer
0035: * (Entrust Technologies, a Nortel majority-owned company) made it available
0036: * worldwide on a royalty-free basis for commercial and non-commercial uses.
0037: * <p>
0038: * The CAST5 encryption algorithm has been designed to allow a key size
0039: * that can vary from 40 bits to 128 bits, in 8-bit increments (that is, the
0040: * allowable key sizes are 40, 48, 56, 64, ..., 112, 120, and 128 bits. For
0041: * variable keysize operation, the specification is as follows:
0042: * <ol>
0043: * <li> For key sizes up to and including 80 bits (i.e., 40, 48, 56, 64, 72,
0044: * and 80 bits), the algorithm is exactly as specified but uses 12
0045: * rounds instead of 16;
0046: * <li> For key sizes greater than 80 bits, the algorithm uses the full 16
0047: * rounds;
0048: * <li> For key sizes less than 128 bits, the key is padded with zero bytes
0049: * (in the rightmost, or least significant, positions) out to 128 bits
0050: * (since the CAST5 key schedule assumes an input key of 128 bits).
0051: * </ol>
0052: * <p>
0053: * References:<br>
0054: * <ul>
0055: * <li>Carlisle Adams,
0056: * <a href="http://www.ietf.org/rfc/html/rfc2144.html">
0057: * RFC 2144</a>, May 1997.
0058: * </ul>
0059: *
0060: * @version $Revision: 1.1 $
0061: * @author Jeroen C. van Gelderen (gelderen@cryptix.org)
0062: * @author Raif S. Naffah (raif@cryptix.org)
0063: * @since Cryptix 2.2.2
0064: */
0065: public final class CAST5 extends BlockCipher {
0066:
0067: // Static variables and constants
0068: //............................................................................
0069:
0070: /** Various constants */
0071: private static final int MIN_NOF_ROUNDS = 12, MAX_NOF_ROUNDS = 16,
0072: BLOCK_SIZE = 8, DEFAULT_NOF_ROUNDS = MAX_NOF_ROUNDS;
0073:
0074: /**
0075: * Compressed S-boxes.
0076: * Compiled size from 33K to 21K. See Blowfish.java for more info.
0077: */
0078: private static String sS0 = "0\u00FB@\u00D4\u009F\u00A0\u00FF\u000Bk\u00EC\u00CD/?%\u008C"
0079: + "z\u001E!?/\u009C\u0000M\u00D3`\u0003\u00E5@\u00CF\u009F\u00C9"
0080: + "I\u00BF\u00D4\u00AF'\u0088\u00BB\u00BD\u00B5\u00E2\u0003@\u0090"
0081: + "\u0098\u00D0\u0096unc\u00A0\u00E0\u0015\u00C3a\u00D2\u00C2\u00E7"
0082: + "f\u001D\"\u00D4\u00FF\u008E(h;o\u00C0\u007F\u00D0Y\u00FF#y\u00C8"
0083: + "w_P\u00E2C\u00C3@\u00D3\u00DF/\u0086V\u0088|\u00A4\u001A\u00A2"
0084: + "\u00D2\u00BD-\u00A1\u00C9\u00E0\u00D64lH\u0019a\u00B7m\u0087"
0085: + "\"T\u000F/*\u00BE2\u00E1\u00AAT\u0016k\"V\u008E:\u00A2\u00D3"
0086: + "A\u00D0f\u00DB@\u00C8\u00A7\u00849/\u0000M\u00FF/-\u00B9\u00D2"
0087: + "\u00DE\u0097\u0094?\u00ACJ\u0097\u00C1\u00D8RvD\u00B7\u00B5\u00F4"
0088: + "7\u00A7\u00B8,\u00BA\u00EF\u00D7Q\u00D1Yo\u00F7\u00F0\u00EDZ"
0089: + "\tz\u001F\u0082{h\u00D0\u0090\u00EC\u00F5.\"\u00B0\u00C0T\u00BC"
0090: + "\u008EY5Km/\u007FP\u00BBd\u00A2\u00D2fI\u0010\u00BE\u00E5\u0081"
0091: + "-\u00B73\"\u0090\u00E9;\u0015\u009F\u00B4\u008E\u00E4\u0011K"
0092: + "\u00FF4]\u00FDE\u00C2@\u00AD1\u0097?\u00C4\u00F6\u00D0.U\u00FC"
0093: + "\u0081e\u00D5\u00B1\u00CA\u00AD\u00A1\u00AC-\u00AE\u00A2\u00D4"
0094: + "\u00B7m\u00C1\u009B\u000CP\u0088\"@\u00F2\u000CnO8\u00A4\u00E4"
0095: + "\u00BF\u00D7O[\u00A2rVL\u001D/\u00C5\u009CS\u0019\u00B9I\u00E3"
0096: + "T\u00B0Fi\u00FE\u00B1\u00B6\u00AB\u008A\u00C7\u0013X\u00DDc\u0085"
0097: + "\u00C5E\u0011\u000F\u0093]WS\u008A\u00D5j9\u0004\u0093\u00E6"
0098: + "=7\u00E0*T\u00F6\u00B3:x}_bv\u00A0\u00B5\u0019\u00A6\u00FC\u00DF"
0099: + "zB j)\u00F9\u00D4\u00D5\u00F6\u001B\u0018\u0091\u00BBr'^\u00AA"
0100: + "P\u0081g8\u0090\u0010\u0091\u00C6\u00B5\u0005\u00EB\u0084\u00C7"
0101: + "\u00CB\u008C*\u00D7Z\u000F\u0087J\u0014'\u00A2\u00D1\u0093k*"
0102: + "\u00D2\u0086\u00AF\u00AAV\u00D2\u0091\u00D7\u0089C`B\\u\r\u0093"
0103: + "\u00B3\u009E&\u0018q\u0084\u00C9l\u0000\u00B3-s\u00E2\u00BB\u0014"
0104: + "\u00A0\u00BE\u00BC<Tb7ydE\u009E\u00AB?2\u008B\u0082w\u0018\u00CF"
0105: + "\u0082Y\u00A2\u00CE\u00A6\u0004\u00EE\u0000.\u0089\u00FEx\u00E6"
0106: + "?\u00AB\tP2_\u00F6\u00C2\u00818?\u0005ic\u00C5\u00C8v\u00CBZ"
0107: + "\u00D6\u00D4\u0099t\u00C9\u00CA\u0018\r\u00CF8\u0007\u0082\u00D5"
0108: + "\u00C7\u00FA\\\u00F6\u008A\u00C3\u0015\u00115\u00E7\u009E\u0013"
0109: + "G\u00DA\u0091\u00D0\u00F4\u000F\u0090\u0086\u00A7\u00E2A\u009E"
0110: + "16bA\u0005\u001E\u00F4\u0095\u00AAW;\u0004J\u0080]\u008DT\u0083"
0111: + "\u0000\u00D0\u00002*<\u00BFd\u00CD\u00DF\u00BAW\u00A6\u008Eu"
0112: + "\u00C67+P\u00AF\u00D3A\u00A7\u00C12u\u0091Z\u000B\u00F5kT\u00BF"
0113: + "\u00AB+\u000B\u0014&\u00ABL\u00C9\u00D7D\u009C\u00CD\u0082\u00F7"
0114: + "\u00FB\u00F2e\u00AB\u0085\u00C5\u00F3\u001BU\u00DB\u0094\u00AA"
0115: + "\u00D4\u00E3$\u00CF\u00A4\u00BD?-\u00EA\u00A3\u00E2\u009E M\u0002"
0116: + "\u00C8\u00BD%\u00AC\u00EA\u00DFU\u00B3\u00D5\u00BD\u009E\u0098"
0117: + "\u00E3\u00121\u00B2*\u00D5\u00ADl\u0095C)\u00DE\u00AD\u00BEE"
0118: + "(\u00D8q\u000Fi\u00AAQ\u00C9\u000F\u00AAxk\u00F6\"Q?\u001E\u00AA"
0119: + "Q\u00A7\u009B*\u00D3D\u00CC{ZA\u00F0\u00D3|\u00FB\u00AD\u001B"
0120: + "\u0006\u0095\u0005A\u00EC\u00E4\u0091\u00B4\u00C32\u00E6\u0003"
0121: + "\"h\u00D4\u00C9`\n\u00CC\u00CE8~m\u00BFk\u00B1ljp\u00FBx\r\u0003"
0122: + "\u00D9\u00C9\u00D4\u00DF9\u00DE\u00E0\u0010c\u00DAG6\u00F4dZ"
0123: + "\u00D3(\u00D8\u00B3G\u00CC\u0096u\u00BB\u000F\u00C3\u0098Q\u001B"
0124: + "\u00FBO\u00FB\u00CC5\u00B5\u008B\u00CFj\u00E1\u001F\n\u00BC\u00BF"
0125: + "\u00C5\u00FEJ\u00A7\n\u00EC\u0010\u00AC9W\n?\u0004D/a\u0088\u00B1"
0126: + "S\u00E09z.W'\u00CBy\u009C\u00EBA\u008F\u001C\u00AC\u00D6\u008D"
0127: + "*\u00D3|\u0096\u0001u\u00CB\u009D\u00C6\u009D\u00FF\t\u00C7["
0128: + "e\u00F0\u00D9\u00DB@\u00D8\u00EC\u000EwyGD\u00EA\u00D4\u00B1"
0129: + "\u001C2t\u00DD$\u00CB\u009E~\u001CT\u00BD\u00F0\u0011D\u00F9"
0130: + "\u00D2$\u000E\u00B1\u0096u\u00B3\u00FD\u00A3\u00AC7U\u00D4|'"
0131: + "\u00AFQ\u00C8_MV\u0090u\u0096\u00A5\u00BB\u0015\u00E6X\u0003"
0132: + "\u0004\u00F0\u00CA\u0004,\u00F1\u0001\u001A7\u00EA\u008D\u00BF"
0133: + "\u00AA\u00DB5\u00BA>J5&\u00FF\u00A0\u00C3{M\t\u00BC0n\u00D9\u0098"
0134: + "\u00A5&fVH\u00F7%\u00FF^V\u009D\u000C\u00EDc\u00D0|c\u00B2\u00CF"
0135: + "p\u000BE\u00E1\u00D5\u00EAP\u00F1\u0085\u00A9(r\u00AF\u001F\u00BD"
0136: + "\u00A7\u00D4#Hp\u00A7\u0087\u000B\u00F3-;MyB\u00E0A\u0098\u000C"
0137: + "\u00D0\u00ED\u00E7&G\r\u00B8\u00F8\u0081\u0081LGMj\u00D7|\u000C"
0138: + "^\\\u00D1#\u0019Y8\u001Br\u0098\u00F5\u00D2\u00F4\u00DB\u00AB"
0139: + "\u0083\u0086Sn/\u001E#\u0083q\u009C\u009E\u00BD\u0091\u00E0F"
0140: + "\u009AVEn\u00DC9 \u000C \u00C8\u00C5q\u0096+\u00DA\u001C\u00E1"
0141: + "\u00E6\u0096\u00FF\u00B1A\u00AB\u0008|\u00CA\u0089\u00B9\u001A"
0142: + "i\u00E7\u0083\u0002\u00CCHC\u00A2\u00F7\u00C5yB\u009E\u00F4}"
0143: + "B{\u0016\u009CZ\u00C9\u00F0I\u00DD\u008F\u000F\u0000\\\u0081"
0144: + "e\u00BF",
0145: sS1 = "0\u00FB@\u00D4\u009F\u00A0\u00FF\u000Bk\u00EC\u00CD/?%\u008C"
0146: + "z\u001E!?/\u009C\u0000M\u00D3`\u0003\u00E5@\u00CF\u009F\u00C9"
0147: + "I\u00BF\u00D4\u00AF'\u0088\u00BB\u00BD\u00B5\u00E2\u0003@\u0090"
0148: + "\u0098\u00D0\u0096unc\u00A0\u00E0\u0015\u00C3a\u00D2\u00C2\u00E7"
0149: + "f\u001D\"\u00D4\u00FF\u008E(h;o\u00C0\u007F\u00D0Y\u00FF#y\u00C8"
0150: + "w_P\u00E2C\u00C3@\u00D3\u00DF/\u0086V\u0088|\u00A4\u001A\u00A2"
0151: + "\u00D2\u00BD-\u00A1\u00C9\u00E0\u00D64lH\u0019a\u00B7m\u0087"
0152: + "\"T\u000F/*\u00BE2\u00E1\u00AAT\u0016k\"V\u008E:\u00A2\u00D3"
0153: + "A\u00D0f\u00DB@\u00C8\u00A7\u00849/\u0000M\u00FF/-\u00B9\u00D2"
0154: + "\u00DE\u0097\u0094?\u00ACJ\u0097\u00C1\u00D8RvD\u00B7\u00B5\u00F4"
0155: + "7\u00A7\u00B8,\u00BA\u00EF\u00D7Q\u00D1Yo\u00F7\u00F0\u00EDZ"
0156: + "\tz\u001F\u0082{h\u00D0\u0090\u00EC\u00F5.\"\u00B0\u00C0T\u00BC"
0157: + "\u008EY5Km/\u007FP\u00BBd\u00A2\u00D2fI\u0010\u00BE\u00E5\u0081"
0158: + "-\u00B73\"\u0090\u00E9;\u0015\u009F\u00B4\u008E\u00E4\u0011K"
0159: + "\u00FF4]\u00FDE\u00C2@\u00AD1\u0097?\u00C4\u00F6\u00D0.U\u00FC"
0160: + "\u0081e\u00D5\u00B1\u00CA\u00AD\u00A1\u00AC-\u00AE\u00A2\u00D4"
0161: + "\u00B7m\u00C1\u009B\u000CP\u0088\"@\u00F2\u000CnO8\u00A4\u00E4"
0162: + "\u00BF\u00D7O[\u00A2rVL\u001D/\u00C5\u009CS\u0019\u00B9I\u00E3"
0163: + "T\u00B0Fi\u00FE\u00B1\u00B6\u00AB\u008A\u00C7\u0013X\u00DDc\u0085"
0164: + "\u00C5E\u0011\u000F\u0093]WS\u008A\u00D5j9\u0004\u0093\u00E6"
0165: + "=7\u00E0*T\u00F6\u00B3:x}_bv\u00A0\u00B5\u0019\u00A6\u00FC\u00DF"
0166: + "zB j)\u00F9\u00D4\u00D5\u00F6\u001B\u0018\u0091\u00BBr'^\u00AA"
0167: + "P\u0081g8\u0090\u0010\u0091\u00C6\u00B5\u0005\u00EB\u0084\u00C7"
0168: + "\u00CB\u008C*\u00D7Z\u000F\u0087J\u0014'\u00A2\u00D1\u0093k*"
0169: + "\u00D2\u0086\u00AF\u00AAV\u00D2\u0091\u00D7\u0089C`B\\u\r\u0093"
0170: + "\u00B3\u009E&\u0018q\u0084\u00C9l\u0000\u00B3-s\u00E2\u00BB\u0014"
0171: + "\u00A0\u00BE\u00BC<Tb7ydE\u009E\u00AB?2\u008B\u0082w\u0018\u00CF"
0172: + "\u0082Y\u00A2\u00CE\u00A6\u0004\u00EE\u0000.\u0089\u00FEx\u00E6"
0173: + "?\u00AB\tP2_\u00F6\u00C2\u00818?\u0005ic\u00C5\u00C8v\u00CBZ"
0174: + "\u00D6\u00D4\u0099t\u00C9\u00CA\u0018\r\u00CF8\u0007\u0082\u00D5"
0175: + "\u00C7\u00FA\\\u00F6\u008A\u00C3\u0015\u00115\u00E7\u009E\u0013"
0176: + "G\u00DA\u0091\u00D0\u00F4\u000F\u0090\u0086\u00A7\u00E2A\u009E"
0177: + "16bA\u0005\u001E\u00F4\u0095\u00AAW;\u0004J\u0080]\u008DT\u0083"
0178: + "\u0000\u00D0\u00002*<\u00BFd\u00CD\u00DF\u00BAW\u00A6\u008Eu"
0179: + "\u00C67+P\u00AF\u00D3A\u00A7\u00C12u\u0091Z\u000B\u00F5kT\u00BF"
0180: + "\u00AB+\u000B\u0014&\u00ABL\u00C9\u00D7D\u009C\u00CD\u0082\u00F7"
0181: + "\u00FB\u00F2e\u00AB\u0085\u00C5\u00F3\u001BU\u00DB\u0094\u00AA"
0182: + "\u00D4\u00E3$\u00CF\u00A4\u00BD?-\u00EA\u00A3\u00E2\u009E M\u0002"
0183: + "\u00C8\u00BD%\u00AC\u00EA\u00DFU\u00B3\u00D5\u00BD\u009E\u0098"
0184: + "\u00E3\u00121\u00B2*\u00D5\u00ADl\u0095C)\u00DE\u00AD\u00BEE"
0185: + "(\u00D8q\u000Fi\u00AAQ\u00C9\u000F\u00AAxk\u00F6\"Q?\u001E\u00AA"
0186: + "Q\u00A7\u009B*\u00D3D\u00CC{ZA\u00F0\u00D3|\u00FB\u00AD\u001B"
0187: + "\u0006\u0095\u0005A\u00EC\u00E4\u0091\u00B4\u00C32\u00E6\u0003"
0188: + "\"h\u00D4\u00C9`\n\u00CC\u00CE8~m\u00BFk\u00B1ljp\u00FBx\r\u0003"
0189: + "\u00D9\u00C9\u00D4\u00DF9\u00DE\u00E0\u0010c\u00DAG6\u00F4dZ"
0190: + "\u00D3(\u00D8\u00B3G\u00CC\u0096u\u00BB\u000F\u00C3\u0098Q\u001B"
0191: + "\u00FBO\u00FB\u00CC5\u00B5\u008B\u00CFj\u00E1\u001F\n\u00BC\u00BF"
0192: + "\u00C5\u00FEJ\u00A7\n\u00EC\u0010\u00AC9W\n?\u0004D/a\u0088\u00B1"
0193: + "S\u00E09z.W'\u00CBy\u009C\u00EBA\u008F\u001C\u00AC\u00D6\u008D"
0194: + "*\u00D3|\u0096\u0001u\u00CB\u009D\u00C6\u009D\u00FF\t\u00C7["
0195: + "e\u00F0\u00D9\u00DB@\u00D8\u00EC\u000EwyGD\u00EA\u00D4\u00B1"
0196: + "\u001C2t\u00DD$\u00CB\u009E~\u001CT\u00BD\u00F0\u0011D\u00F9"
0197: + "\u00D2$\u000E\u00B1\u0096u\u00B3\u00FD\u00A3\u00AC7U\u00D4|'"
0198: + "\u00AFQ\u00C8_MV\u0090u\u0096\u00A5\u00BB\u0015\u00E6X\u0003"
0199: + "\u0004\u00F0\u00CA\u0004,\u00F1\u0001\u001A7\u00EA\u008D\u00BF"
0200: + "\u00AA\u00DB5\u00BA>J5&\u00FF\u00A0\u00C3{M\t\u00BC0n\u00D9\u0098"
0201: + "\u00A5&fVH\u00F7%\u00FF^V\u009D\u000C\u00EDc\u00D0|c\u00B2\u00CF"
0202: + "p\u000BE\u00E1\u00D5\u00EAP\u00F1\u0085\u00A9(r\u00AF\u001F\u00BD"
0203: + "\u00A7\u00D4#Hp\u00A7\u0087\u000B\u00F3-;MyB\u00E0A\u0098\u000C"
0204: + "\u00D0\u00ED\u00E7&G\r\u00B8\u00F8\u0081\u0081LGMj\u00D7|\u000C"
0205: + "^\\\u00D1#\u0019Y8\u001Br\u0098\u00F5\u00D2\u00F4\u00DB\u00AB"
0206: + "\u0083\u0086Sn/\u001E#\u0083q\u009C\u009E\u00BD\u0091\u00E0F"
0207: + "\u009AVEn\u00DC9 \u000C \u00C8\u00C5q\u0096+\u00DA\u001C\u00E1"
0208: + "\u00E6\u0096\u00FF\u00B1A\u00AB\u0008|\u00CA\u0089\u00B9\u001A"
0209: + "i\u00E7\u0083\u0002\u00CCHC\u00A2\u00F7\u00C5yB\u009E\u00F4}"
0210: + "B{\u0016\u009CZ\u00C9\u00F0I\u00DD\u008F\u000F\u0000\\\u0081"
0211: + "e\u00BF",
0212: sS2 = "\u001F \u0010\u0094\u00EF\u000B\u00A7[i\u00E3\u00CF~9?C\u0080"
0213: + "\u00FEa\u00CFz\u00EE\u00C5 zU\u0088\u009C\u0094r\u00FC\u0006"
0214: + "Q\u00AD\u00A7\u00EFyN\u001Dr5\u00D5Zc\u00CE\u00DE\u00046\u00BA"
0215: + "\u0099\u00C40\u00EF_\u000C\u0007\u0094\u0018\u00DC\u00DB}\u00A1"
0216: + "\u00D6\u00EF\u00F3\u00A0\u00B5/{Y\u00E86\u0005\u00EE\u0015\u00B0"
0217: + "\u0094\u00E9\u00FF\u00D9\t\u00DCD\u0000\u0086\u00EF\u0094DY\u00BA"
0218: + "\u0083\u00CC\u00B3\u00E0\u00C3\u00CD\u00FB\u00D1\u00DAA\u0081"
0219: + ";\t*\u00B1\u00F9\u0097\u00F1\u00C1\u00A5\u00E6\u00CF{\u0001B"
0220: + "\r\u00DB\u00E4\u00E7\u00EF[%\u00A1\u00FFA\u00E1\u0080\u00F8\u0006"
0221: + "\u001F\u00C4\u0010\u0080\u0017\u009B\u00EEz\u00D3z\u00C6\u00A9"
0222: + "\u00FEX0\u00A4\u0098\u00DE\u008B\u007Fw\u00E8?Ny\u0092\u0092"
0223: + "i$\u00FA\u009F{\u00E1\u0013\u00C8[\u00AC\u00C4\u0000\u0083\u00D7"
0224: + "P5%\u00F7\u00EAa_b\u00141T\rUKc]h\u0011!\u00C8f\u00C3Y=c\u00CF"
0225: + "s\u00CE\u00E24\u00C0\u00D4\u00D8~\u0087\\g+!\u0007\u001Fa\u0081"
0226: + "9\u00F7b\u007F6\u001E0\u0084\u00E4\u00EBW;`/d\u00A4\u00D6:\u00CD"
0227: + "\u009C\u001B\u00BCF5\u009E\u0081\u0003-'\u0001\u00F5\u000C\u0099"
0228: + "\u0084z\u00B4\u00A0\u00E3\u00DFy\u00BAl\u00F3\u008C\u0010\u0084"
0229: + "0\u0094%7\u00A9^\u00F4oo\u00FE\u00A1\u00FF;\u001F \u008C\u00FB"
0230: + "j\u008FE\u008Ct\u00D9\u00E0\u00A2'N\u00C7:4\u00FC\u0088Oi>M\u00E8"
0231: + "\u00DF\u00EF\u000E\u0000\u00885Yd\u008D\u008AE8\u008C\u001D\u0080"
0232: + "Cfr\u001D\u009B\u00FD\u00A5\u0086\u0084\u00BB\u00E8%c3\u0084"
0233: + "N\u0082\u0012\u0012\u008D\u0080\u0098\u00FE\u00D3?\u00B4\u00CE"
0234: + "(\n\u00E1'\u00E1\u009B\u00A5\u00D5\u00A6\u00C2R\u00E4\u0097T"
0235: + "\u00BD\u00C5\u00D6U\u00DD\u00EBfpdw\u0084\u000BM\u00A1\u00B6"
0236: + "\u00A8\u0001\u0084\u00DB&\u00A9\u00E0\u00B5g\u0014!\u00F0C\u00B7"
0237: + "\u00E5\u00D0X`T\u00F00\u0084\u0006o\u00F4r\u00A3\u001A\u00A1"
0238: + "S\u00DA\u00DCGU\u00B5b]\u00BFhV\u001B\u00E6\u0083\u00CAk\u0094"
0239: + "-n\u00D2;\u00EC\u00CF\u0001\u00DB\u00A6\u00D3\u00D0\u00BA\u00B6"
0240: + "\u0080=\\\u00AFw\u00A7\t3\u00B4\u00A3L9{\u00C8\u00D6^\u00E2+"
0241: + "\u0095_\u000ES\u0004\u0081\u00EDoa \u00E7Cd\u00B4^\u0013x\u00DE"
0242: + "\u0018c\u009B\u0088\u001C\u00A1\"\u00B9g&\u00D1\u0080I\u00A7"
0243: + "\u00E8\"\u00B7\u00DA{^U-%Rr\u00D27y\u00D2\u0095\u001C\u00C6\r"
0244: + "\u0089LH\u008C\u00B4\u0002\u001B\u00A4\u00FE[\u00A4\u00B0\u009F"
0245: + "k\u001C\u00A8\u0015\u00CF\u00A2\u000C0\u0005\u0088q\u00DFc\u00B9"
0246: + "\u00DE/\u00CB\u000C\u00C6\u00C9\u00E9\u000B\u00EE\u00FFS\u00E3"
0247: + "!E\u0017\u00B4T(5\u009Fc)<\u00EEA\u00E7)n\u001D-|P\u0004R\u0086"
0248: + "\u001Ef\u0085\u00F3\u00F34\u0001\u00C60\u00A2,\u00951\u00A7\u0008"
0249: + "P`\u0093\u000F\u0013s\u00F9\u0084\u0017\u00A1&\u0098Y\u00ECd"
0250: + "\\DR\u00C8w\u00A9\u00CD\u00FF3\u00A6\u00A0+\u0017A|\u00BA\u00D9"
0251: + "\u00A2!\u0080\u0003oP\u00D9\u009C\u0008\u00CB?Ha\u00C2k\u00D7"
0252: + "ed\u00A3\u00F6\u00AB\u00804&v%\u00A7^{\u00E4\u00E6\u00D1\u00FC"
0253: + " \u00C7\u0010\u00E6\u00CD\u00F0\u00B6\u0080\u0017\u0084M;1\u00EE"
0254: + "\u00F8M~\u0008$\u00E4,\u00CBI\u00EB\u0084j;\u00AE\u008F\u00F7"
0255: + "x\u0088\u00EE]`\u00F6z\u00F7Vs/\u00DD\\\u00DB\u00A1\u00161\u00C1"
0256: + "0\u00F6oC\u00B3\u00FA\u00ECT\u0015\u007F\u00D7\u00FA\u00EF\u0085"
0257: + "y\u00CC\u00D1R\u00DEX\u00DB/\u00FD^\u008F2\u00CE\u00190j\u00F9"
0258: + "z\u0002\u00F0>\u00F8\u00991\u009A\u00D5\u00C2B\u00FA\u000F\u00A7"
0259: + "\u00E3\u00EB\u00B0\u00C6\u008EI\u0006\u00B8\u00DA#\u000C\u0080"
0260: + "\u00820(\u00DC\u00DE\u00F3\u00C8\u00D3_\u00B1q\u0008\u008A\u001B"
0261: + "\u00C8\u00BE\u00C0\u00C5`a\u00A3\u00C9\u00E8\u00BC\u00A8\u00F5"
0262: + "M\u00C7/\u00EF\u00FA\"\u0082.\u0099\u0082\u00C5p\u00B4\u00D8"
0263: + "\u00D9N\u0089\u008B\u001C4\u00BC0\u001E\u0016\u00E6';\u00E9y"
0264: + "\u00B0\u00FF\u00EA\u00A6a\u00D9\u00B8\u00C6\u0000\u00B2Hi\u00B7"
0265: + "\u00FF\u00CE?\u0008\u00DC(;C\u00DA\u00F6Z\u00F7\u00E1\u0097\u0098"
0266: + "v\u0019\u00B7/\u008F\u001C\u009B\u00A4\u00DC\u00867\u00A0\u0016"
0267: + "\u00A7\u00D3\u00B1\u009F\u00C3\u0093\u00B7\u00A7\u0013n\u00EB"
0268: + "\u00C6\u00BC\u00C6>\u001AQ7B\u00EFh(\u00BCR\u0003e\u00D6-jw\u00AB"
0269: + "5'\u00EDK\u0082\u001F\u00D2\u0016\t\\n.\u00DB\u0092\u00F2\u00FB"
0270: + "^\u00EA)\u00CB\u0014X\u0092\u00F5\u0091XO\u007FT\u0083i{&g\u00A8"
0271: + "\u00CC\u0085\u0019`H\u008CK\u00AC\u00EA\u00838`\u00D4\r#\u00E0"
0272: + "\u00F9l8~\u008A\n\u00E6\u00D2I\u00B2\u0084`\u000C\u00D85s\u001D"
0273: + "\u00DC\u00B1\u00C6G\u00ACLV\u00EA>\u00BD\u0081\u00B3#\u000E\u00AB"
0274: + "\u00B0d8\u00BC\u0087\u00F0\u00B5\u00B1\u00FA\u008F^\u00A2\u00B3"
0275: + "\u00FC\u0018FB\n\u0003kzO\u00B0\u0089\u00BDd\u009D\u00A5\u0089"
0276: + "\u00A3EA^\\\u0003\u0083#>];\u00B9C\u00D7\u0095r~m\u00D0|\u0006"
0277: + "\u00DF\u00DF\u001Ell\u00C4\u00EFq`\u00A59s\u00BF\u00BEp\u0083"
0278: + "\u0087v\u0005E#\u00EC\u00F1",
0279: sS3 = "\u008D\u00EF\u00C2@%\u00FA]\u009F\u00EB\u0090=\u00BF\u00E8\u0010"
0280: + "\u00C9\u0007G`\u007F\u00FF6\u009F\u00E4K\u008C\u001F\u00C6D\u00AE"
0281: + "\u00CE\u00CA\u0090\u00BE\u00B1\u00F9\u00BF\u00EE\u00FB\u00CA"
0282: + "\u00EA\u00E8\u00CF\u0019PQ\u00DF\u0007\u00AE\u0092\u000E\u0088"
0283: + "\u0006\u00F0\u00AD\u0005H\u00E1<\u008D\u0083\u0092p\u0010\u00D5"
0284: + "\u0011\u0010}\u009F\u0007d}\u00B9\u00B2\u00E3\u00E4\u00D4=O("
0285: + "^\u00B9\u00AF\u00A8 \u00FA\u00DE\u0082\u00E0\u00A0g&\u008B\u0082"
0286: + "ry.U?\u00B2\u00C0H\u009A\u00E2+\u00D4\u00EF\u0097\u0094\u0012"
0287: + "^?\u00BC!\u00FF\u00FC\u00EE\u0082[\u001B\u00FD\u0092U\u00C5\u00ED"
0288: + "\u0012W\u00A2@N\u001A\u0083\u0002\u00BA\u00E0\u007F\u00FFR\u0082"
0289: + "F\u00E7\u008EW\u0014\u000E3s\u00F7\u00BF\u008C\u009F\u0081\u0088"
0290: + "\u00A6\u00FCN\u00E8\u00C9\u0082\u00B5\u00A5\u00A8\u00C0\u001D"
0291: + "\u00B7W\u009F\u00C2dg\tO1\u00F2\u00BD?_@\u00FF\u00F7\u00C1\u001F"
0292: + "\u00B7\u008D\u00FC\u008Ek\u00D2\u00C1C{\u00E5\u009B\u0099\u00B0"
0293: + "=\u00BF\u00B5\u00DB\u00C6Kc\u008D\u00C0\u00E6U\u0081\u009D\u0099"
0294: + "\u00A1\u0097\u00C8\u001CJ\u0001-n\u00C5\u0088J(\u00CC\u00C3o"
0295: + "q\u00B8C\u00C2\u0013l\u0007C\u00F1\u0083\t\u0089<\u000F\u00ED"
0296: + "\u00DD_/\u007F\u00E8P\u00D7\u00C0\u007F~\u0002P\u007F\u00BFZ"
0297: + "\u00FB\u009A\u0004\u00A7G\u00D2\u00D0\u0016Q\u0019.\u00AFp\u00BF"
0298: + ">X\u00C3\u0013\u0080_\u00980.r|\u00C3\u00C4\n\u000F\u00B4\u0002"
0299: + "\u000F\u007F\u00EF\u0082\u008C\u0096\u00FD\u00AD],*\u00AE\u008E"
0300: + "\u00E9\u009AIP\u00DA\u0088\u00B8\u0084'\u00F4\u00A0\u001E\u00AC"
0301: + "W\u0090yo\u00B4I\u0082R\u00DC\u0015\u00EF\u00BD}\u009B\u00A6"
0302: + "rY}\u00AD\u00A8@\u00D8E\u00F5E\u0004\u00FA]t\u0003\u00E8>\u00C3"
0303: + "\u0005O\u0091u\u001A\u0092Vi\u00C2#\u00EF\u00E9A\u00A9\u0003"
0304: + "\u00F1.`'\r\u00F2\u0002v\u00E4\u00B6\u0094\u00FDet\u0092y\u0085"
0305: + "\u00B2\u0082v\u00DB\u00CB\u0002w\u0081v\u00F8\u00AF\u0091\u008D"
0306: + "NH\u00F7\u009E\u008Fam\u00DF\u00E2\u009D\u0084\u000E\u0084/}"
0307: + "\u00834\u000C\u00E5\u00C8\u0096\u00BB\u00B6\u0082\u0093\u00B4"
0308: + "\u00B1H\u00EF0<\u00AB\u0098O\u00AF(w\u009F\u00AF\u009B\u0092"
0309: + "\u00DCV\r\"M\u001E \u00847\u00AA\u0088})\u00DC\u0096'V\u00D3"
0310: + "\u00DC\u008B\u0090|\u00EE\u00B5\u001F\u00D2@\u00E7\u00C0|\u00E3"
0311: + "\u00E5f\u00B4\u00A1\u00C3\u00E9a^<\u00F8 \u009D`\u0094\u00D1"
0312: + "\u00E3\u00CD\u009C\u00A3A\\vF\u000E\u0000\u00EA\u0098;\u00D4"
0313: + "\u00D6x\u0081\u00FDGW,\u00F7l\u00ED\u00D9\u00BD\u00A8\"\u009C"
0314: + "\u0012}\u00AD\u00AAC\u008A\u0007N\u001F\u0097\u00C0\u0090\u0008"
0315: + "\u001B\u00DB\u008A\u0093\u00A0~\u00BE\u00B98\u00CA\u0015\u0097"
0316: + "\u00B0<\u00FF=\u00C2\u00C0\u00F8\u008D\u001A\u00B2\u00ECd8\u000E"
0317: + "Qh\u00CC{\u00FB\u00D9\u000F'\u0088\u0012I\u0001\u0081]\u00E5"
0318: + "\u00FF\u00D4\u00DD~\u00F8jv\u00A2\u00E2\u0014\u00B9\u00A4\u0003"
0319: + "h\u0092]\u0095\u008FK9\u00FF\u00FA\u00BA9\u00AE\u00E9\u00A4\u00FF"
0320: + "\u00D3\u000B\u00FA\u00F7\u0093;mI\u0086#\u0019<\u00BC\u00FA'"
0321: + "buE\u0082\\\u00F4za\u00BD\u008B\u00A0\u00D1\u001EB\u00D1\u00CE"
0322: + "\u00AD\u0004\u00F4\u0012~\u00A3\u0092\u0010B\u008D\u00B7\u0082"
0323: + "r\u00A9r\u0092p\u00C4\u00A8\u0012}\u00E5\u000B([\u00A1\u00C8"
0324: + "<b\u00F4O5\u00C0\u00EA\u00A5\u00E8\u0005\u00D21B\u0089)\u00FB"
0325: + "\u00B4\u00FC\u00DF\u0082O\u00B6jS\u000E}\u00C1[\u001F\u0008\u001F"
0326: + "\u00AB\u0010\u0086\u0018\u00AE\u00FC\u00FD\u0008m\u00F9\u00FF"
0327: + "(\u0089iK\u00CC\u0011#j\\\u00AE\u0012\u00DE\u00CAM,?\u008C\u00C5"
0328: + "\u00D2\u00D0-\u00FE\u00F8\u00EFX\u0096\u00E4\u00CFR\u00DA\u0095"
0329: + "\u0015[gIJH\u008C\u00B9\u00B6\u00A8\u000C\\\u008F\u0082\u00BC"
0330: + "\u0089\u00D3kE:`\u00947\u00EC\u0000\u00C9\u00A9DqRS\n\u0087K"
0331: + "I\u00D7s\u00BC@|4g\u001C\u0002q~\u00F6O\u00EBU6\u00A2\u00D0/"
0332: + "\u00FF\u00D2\u00BF`\u00C4\u00D4?\u0003\u00C0P\u00B4\u00EFm\u0007"
0333: + "G\u008C\u00D1\u0000n\u0018\u0088\u00A2\u00E5?U\u00B9\u00E6\u00D4"
0334: + "\u00BC\u00A2\u0004\u0080\u0016\u0097W83\u00D7 }g\u00DE\u000F"
0335: + "\u008F=r\u00F8{3\u00AB\u00CCO3v\u0088\u00C5]{\u0000\u00A6\u00B0"
0336: + "\u0094{\u0000\u0001W\u0000u\u00D2\u00F9\u00BB\u0088\u00F8\u0089"
0337: + "B\u0001\u009EBd\u00A5\u00FF\u0085c\u0002\u00E0r\u00DB\u00D9+"
0338: + "\u00EE\u0097\u001Bin\u00A2/\u00DE_\u0008\u00AE+\u00AFzam\u00E5"
0339: + "\u00C9\u0087g\u00CF\u001F\u00EB\u00D2a\u00EF\u00C8\u00C2\u00F1"
0340: + "\u00AC%q\u00CC\u00829\u00C2g!L\u00B8\u00B1\u00E5\u0083\u00D1"
0341: + "\u00B7\u00DC>b\u007F\u0010\u00BD\u00CE\u00F9\n\\8\u000F\u00F0"
0342: + "D=`nm\u00C6`T:IW'\u00C1H+\u00E9\u008A\u001D\u008A\u00B4\u0017"
0343: + "8 \u00E1\u00BE$\u00AF\u0096\u00DA\u000FhE\u0084%\u0099\u0083"
0344: + ";\u00E5`\rE}(/\u0093P\u00834\u00B3b\u00D9\u001D\u0011 +m\u008D"
0345: + "\u00A0d+\u001E1\u009C0Z\u0000R\u00BC\u00E6\u0088\u001B\u0003"
0346: + "X\u008A\u00F7\u00BA\u00EF\u00D5AB\u00ED\u009C\u00A41\\\u0011"
0347: + "\u00832>\u00C5\u00DF\u00EFF6\u00A13\u00C5\u0001\u00E9\u00D3S"
0348: + "\u001C\u00EE57\u0083",
0349: sS4 = "\u009D\u00B3\u0004 \u001F\u00B6\u00E9\u00DE\u00A7\u00BE{\u00EF"
0350: + "\u00D2s\u00A2\u0098JO{\u00DBd\u00AD\u008CW\u0085Q\u0004C\u00FA"
0351: + "\u0002\u000E\u00D1~(z\u00FF\u00E6\u000F\u00B6c\t_5\u00A1y\u00EB"
0352: + "\u00F1 \u00FD\u0005\u009DCd\u0097\u00B7\u00B1\u00F3d\u001Fc$"
0353: + "\u001EJ\u00DF(\u0014\u007F_O\u00A2\u00B8\u00CD\u00C9C\u0000@"
0354: + "\u000C\u00C3\" \u00FD\u00D3\u000B0\u00C0\u00A57O\u001D-\u0000"
0355: + "\u00D9$\u0014{\u0015\u00EEM\u0011\u001A\u000F\u00CAQgq\u00FF"
0356: + "\u0090L-\u0019_\u00FE\u001A\u0005d_\u000C\u0013\u00FE\u00FE\u0008"
0357: + "\u001B\u0008\u00CA\u0005\u0017\u0001!\u0080S\u0001\u0000\u00E8"
0358: + ">^\u00FE\u00AC\u009A\u00F4\u00F8\u007F\u00E7'\u0001\u00D2\u00B8"
0359: + "\u00EE_\u0006\u00DFBa\u00BB\u009E\u009B\u008Ar\u0093\u00EA%\u00CE"
0360: + "\u0084\u00FF\u00DF\u00F5q\u0088\u0001=\u00D6K\u0004\u00A2o&;"
0361: + "~\u00D4\u0084\u0000T~\u00EB\u00E6DmL\u00A0l\u00F3\u00D6\u00F5"
0362: + "&I\u00AB\u00DF\u00AE\u00A0\u00C7\u00F563\u008C\u00C1P?~\u0093"
0363: + "\u00D3w a\u0011\u00B68\u00E1rP\u000E\u0003\u00F8\u000E\u00B2"
0364: + "\u00BB\u00AB\u00E0P.\u00EC\u008Dw\u00DEW\u0097\u001E\u0081\u00E1"
0365: + "OgF\u00C93T\u0000i 1\u008F\u0008\u001D\u00BB\u0099\u00FF\u00C3"
0366: + "\u0004\u00A5M5\u0018\u0005\u007F=\\\u00E3\u00A6\u00C8f\u00C6"
0367: + "][\u00CC\u00A9\u00DA\u00ECo\u00EA\u009F\u0092o\u0091\u009FF\""
0368: + "/9\u0091F}\u00A5\u00BFm\u008E\u0011C\u00C4OC\u0095\u0083\u0002"
0369: + "\u00D0!N\u00EB\u0002 \u0083\u00B8?\u00B6\u0018\u000C\u0018\u00F8"
0370: + "\u0093\u001E(\u0016X\u00E6&Hn>\u008B\u00D7\u008Aptw\u00E4\u00C1"
0371: + "\u00B5\u0006\u00E0|\u00F3-\n%y\t\u008B\u0002\u00E4\u00EA\u00BB"
0372: + "\u0081(\u0012;#i\u00DE\u00AD8\u0015t\u00CA\u0016\u00DF\u0087"
0373: + "\u001Bb!\u001C@\u00B7\u00A5\u001A\u009E\u00F9\u0000\u00147{\u0004"
0374: + "\u001E\u008A\u00C8\t\u0011@\u0003\u00BDY\u00E4\u00D2\u00E3\u00D1"
0375: + "V\u00D5O\u00E8v\u00D5/\u0091\u00A3@U{\u00E8\u00DE\u0000\u00EA"
0376: + "\u00E4\u00A7\u000C\u00E5\u00C2\u00ECM\u00B4\u00BB\u00A6\u00E7"
0377: + "V\u00BD\u00FF\u00DD3i\u00AC\u00EC\u0017\u00B05\u0006W#'\u0099"
0378: + "\u00AF\u00C8\u00B0V\u00C8\u00C3\u0091ke\u0081\u001C^\u0014a\u0019"
0379: + "n\u0085\u00CBu\u00BE\u0007\u00C0\u0002\u00C22Uw\u0089?\u00F4"
0380: + "\u00EC[\u00BF\u00C9-\u00D0\u00EC;%\u00B7\u0080\u001A\u00B7\u008D"
0381: + "m;$ \u00C7c\u00EF\u00C3f\u00A5\u00FC\u009C8(\u0080\n\u00CE2\u0005"
0382: + "\u00AA\u00C9T\u008A\u00EC\u00A1\u00D7\u00C7\u0004\u001A\u00FA"
0383: + "2\u001D\u0016bZg\u0001\u0090,\u009BuzT1\u00D4w\u00F7\u0091&\u00B0"
0384: + "16\u00CCo\u00DB\u00C7\u000B\u008BF\u00D9\u00E6jHV\u00E5Zy\u0002"
0385: + "jL\u00EBRC~\u00FF/\u008Fv\u00B4\r\u00F9\u0080\u00A5\u0086t\u00CD"
0386: + "\u00E3\u00ED\u00DA\u0004\u00EB\u0017\u00A9\u00BE\u0004,\u0018"
0387: + "\u00F4\u00DF\u00B7t\u007F\u009D\u00AB*\u00F7\u00B4\u00EF\u00C3"
0388: + "M .\tk|\u0017A\u00A2T\u00E5\u00B6\u00A05!=B\u00F6,\u001C|&a\u00C2"
0389: + "\u00F5\u000FeR\u00DA\u00F9\u00D2\u00C21\u00F8%\u0013\u000Fi\u00D8"
0390: + "\u0016\u007F\u00A2\u0004\u0018\u00F2\u00C8\u0000\u001A\u0096"
0391: + "\u00A6\r\u0015&\u00ABc1\\!^\nr\u00ECI\u00BA\u00FE\u00FD\u0018"
0392: + "y\u0008\u00D9\u008D\r\u00BD\u00861\u0011p\u00A7>\u009Bd\u000C"
0393: + "\u00CC>\u0010\u00D7\u00D5\u00CA\u00D3\u00B6\u000C\u00AE\u00C3"
0394: + "\u0088\u00F70\u0001\u00E1lr\u008A\u00FFq\u00EA\u00E2\u00A1\u001F"
0395: + "\u009A\u00F3n\u00CF\u00CB\u00D1/\u00C1\u00DE\u0084\u0017\u00AC"
0396: + "\u0007\u00BEk\u00CBD\u00A1\u00D8\u008B\u009B\u000FV\u00019\u0088"
0397: + "\u00C3\u00B1\u00C5/\u00CA\u00B4\u00BE1\u00CD\u00D8x(\u0006\u0012"
0398: + "\u00A3\u00A4\u00E2o}\u00E52X\u00FD~\u00B6\u00D0\u001E\u00E9\u0000"
0399: + "$\u00AD\u00FF\u00C2\u00F4\u0099\u000F\u00C5\u0097\u0011\u00AA"
0400: + "\u00C5\u0000\u001D{\u0095\u0082\u00E5\u00E7\u00D2\u0010\u0098"
0401: + "s\u00F6\u0000a0\u0096\u00C3-\u0095!\u00AD\u00A1!\u00FF)\u0090"
0402: + "\u0084\u0015\u007F\u00BB\u0097\u007F\u00AF\u009E\u00B3\u00DB"
0403: + ")\u00C9\u00ED*\\\u00E2\u00A4e\u00A70\u00F3,\u00D0\u00AA?\u00E8"
0404: + "\u008A\\\u00C0\u0091\u00D4\u009E,\u00E7\u000C\u00E4T\u00A9\u00D6"
0405: + "\n\u00CD\u0086\u0001_\u0019\u0019w\u0007\u0091\u0003\u00DE\u00A0"
0406: + ":\u00F6x\u00A8V^\u00DE\u00E3V\u00DF!\u00F0\\\u00BE\u008Bu\u00E3"
0407: + "\u0087\u00B3\u00C5\u0006Q\u00B8\u00A5\u00C3\u00EF\u00D8\u00EE"
0408: + "\u00B6\u00D2\u00E5#\u00BEw\u00C2\u0015E)/i\u00EF\u00DF\u00AF"
0409: + "\u00E6z\u00FB\u00F4p\u00C4\u00B2\u00F3\u00E0\u00EB[\u00D6\u00CC"
0410: + "\u0098v9\u00E4F\u000C\u001F\u00DA\u00858\u0019\u0087\u0083/\u00CA"
0411: + "\u0000sg\u00A9\u0091D\u00F8)k)\u009EI/\u00C2\u0095\u0092f\u00BE"
0412: + "\u00AB\u00B5gni\u009B\u00D3\u00DD\u00DA\u00DF~\u0005/\u00DB%"
0413: + "p\u001C\u001B^Q\u00EE\u00F6S$\u00E6j\u00FC\u00E3l\u0003\u0016"
0414: + "\u00CC\u0004\u0086D!>\u00B7\u00DCY\u00D0ye)\u001F\u00CC\u00D6"
0415: + "\u00FDCA\u00829y\u0093+\u00CD\u00F6\u00B6W\u00C3MN\u00DF\u00D2"
0416: + "\u0082z\u00E5)\u000C<\u00B9Sk\u0085\u001E \u00FE\u00983U~\u0013"
0417: + "\u00EC\u00F0\u00B0\u00D3\u00FF\u00B3r?\u0085\u00C5\u00C1\n\u00EF"
0418: + "~\u00D2",
0419: sS5 = "~\u00C9\u000C\u0004,nt\u00B9\u009B\u000Ef\u00DF\u00A63y\u0011"
0420: + "\u00B8j\u007F\u00FF\u001D\u00D3X\u00F5D\u00DD\u009DD\u00171\u0016"
0421: + "\u007F\u0008\u00FB\u00F1\u00FA\u00E7\u00F5\u0011\u00CC\u00D2"
0422: + "\u0005\u001B\u0000sZ\u00BA\u0000*\u00B7\"\u00D88c\u0081\u00CB"
0423: + "\u00AC\u00F6$:i\u00BE\u00FDz\u00E6\u00A2\u00E7\u007F\u00F0\u00C7"
0424: + " \u00CD\u00C4IH\u0016\u00CC\u00F5\u00C1\u00808\u0085\u0016@\u0015"
0425: + "\u00B0\u00A8H\u00E6\u008B\u0018\u00CBL\u00AA\u00DE\u00FF_H\n"
0426: + "\u0001\u0004\u0012\u00B2\u00AA%\u0098\u0014\u00FCA\u00D0\u00EF"
0427: + "\u00E2N@\u00B4\u008D$\u008E\u00B6\u00FB\u008D\u00BA\u001C\u00FE"
0428: + "A\u00A9\u009B\u0002\u001AU\n\u0004\u00BA\u008Fe\u00CBrQ\u00F4"
0429: + "\u00E7\u0095\u00A5\u0017%\u00C1\u0006\u00EC\u00D7\u0097\u00A5"
0430: + "\u0098\n\u00C59\u00B9\u00AAMy\u00FEj\u00F2\u00F3\u00F7ch\u00AF"
0431: + "\u0080@\u00ED\u000C\u009EV\u0011\u00B4\u0095\u008B\u00E1\u00EB"
0432: + "Z\u0088\u0087\t\u00E6\u00B0\u00D7\u00E0qVN)\u00FE\u00A7cf\u00E5"
0433: + "-\u0002\u00D1\u00C0\u0000\u00C4\u00AC\u008E\u0005\u0093w\u00F5"
0434: + "q\u000C\u00057*W\u00855\u00F2\"a\u00BE\u0002\u00D6B\u00A0\u00C9"
0435: + "\u00DF\u0013\u00A2\u0080t\u00B5[\u00D2h!\u0099\u00C0\u00D4!\u00E5"
0436: + "\u00ECS\u00FB<\u00E8\u00C8\u00AD\u00ED\u00B3(\u00A8\u007F\u00C9"
0437: + "=\u0095\u0099\u0081\\\u001F\u00F9\u0000\u00FE8\u00D3\u0099\u000C"
0438: + "N\u00FF\u000B\u0006$\u0007\u00EA\u00AA/O\u00B1O\u00B9iv\u0090"
0439: + "\u00C7\u0095\u0005\u00B0\u00A8\u00A7t\u00EFU\u00A1\u00FF\u00E5"
0440: + "\u009C\u00A2\u00C2\u00A6\u00B6-'\u00E6jBc\u00DFe\u0000\u001F"
0441: + "\u000E\u00C5\tf\u00DF\u00DDU\u00BC)\u00DE\u0006U\u0091\u001E"
0442: + "s\u009A\u0017\u00AF\u0089u2\u00C7\u0091\u001C\u0089\u00F8\u0094"
0443: + "h\r\u0001\u00E9\u0080RGU\u00F4\u0003\u00B6<\u00C9\u000C\u00C8"
0444: + "D\u00B2\u00BC\u00F3\u00F0\u00AA\u0087\u00AC6\u00E9\u00E5:t&\u0001"
0445: + "\u00B3\u00D8+\u001A\u009EtId\u00EE-~\u00CD\u00DB\u00B1\u00DA"
0446: + "\u0001\u00C9I\u0010\u00B8h\u00BF\u0080\r&\u00F3\u00FD\u0093B"
0447: + "\u00ED\u00E7\u0004\u00A5\u00C2\u0084cg7\u00B6P\u00F5\u00B6\u0016"
0448: + "\u00F2Gf\u00E3\u008E\u00CA6\u00C1\u0013n\u0005\u00DB\u00FE\u00F1"
0449: + "\u0083\u0091\u00FB\u0088z7\u00D6\u00E7\u00F7\u00D4\u00C7\u00FB"
0450: + "}\u00C90c\u00FC\u00DF\u00B6\u00F5\u0089\u00DE\u00EC)A\u00DA&"
0451: + "\u00E4f\u0095\u00B7Vd\u0019\u00F6T\u00EF\u00C5\u00D0\u008DX\u00B7"
0452: + "H\u0092T\u0001\u00C1\u00BA\u00CB\u007F\u00E5\u00FFU\u000F\u00B6"
0453: + "\u00080I[\u00B5\u00D0\u00E8\u0087\u00D7.Z\u00ABjn\u00E1\":f\u00CE"
0454: + "\u00C6+\u00F3\u00CD\u009E\u0008\u0085\u00F9h\u00CB>G\u0008l\u0001"
0455: + "\u000F\u00A2\u001D\u00E8 \u00D1\u008Bi\u00DE\u00F3\u00F6Ww\u00FA"
0456: + "\u0002\u00C3\u00F6@~\u00DA\u00C3\u00CB\u00B3\u00D5P\u0017\u0093"
0457: + "\u0008M\u00B0\u00D7\u000E\u00BA\n\u00B3x\u00D5\u00D9Q\u00FB\u000C"
0458: + "\u00DE\u00D7\u00DAVA$\u00BB\u00E4\u0094\u00CA\u000BV\u000FWU"
0459: + "\u00D1\u00E0\u00E1\u00E5na\u0084\u00B5\u00BEX\n$\u009F\u0094"
0460: + "\u00F7K\u00C0\u00E3'\u0088\u008E\u009F{Ua\u00C3\u00DC\u0002\u0080"
0461: + "\u0005hw\u0015dlk\u00D7D\u0090M\u00B3f\u00B4\u00F0\u00A3\u00C0"
0462: + "\u00F1d\u008Ai~\u00D5\u00AFI\u00E9/\u00F60\u009E7O,\u00B65j\u0085"
0463: + "\u0080\u0085sI\u0091\u00F8@v\u00F0\u00AE\u0002\u0008;\u00E8M"
0464: + "(B\u001C\u009ADH\u0094\u0006snL\u00B8\u00C1\t)\u0010\u008B\u00C9"
0465: + "_\u00C6}\u0086\u009C\u00F4\u0013Oao.w\u0011\u008D\u00B3\u001B"
0466: + "+\u00E1\u00AA\u0090\u00B4r<\u00A5\u00D7\u0017}\u0016\u001B\u00BA"
0467: + "\u009C\u00AD\u0090\u0010\u00AFF+\u00A2\u009F\u00E4Y\u00D2E\u00D3"
0468: + "EY\u00D9\u00F2\u00DA\u0013\u00DB\u00C6T\u0087\u00F3\u00E4\u00F9"
0469: + "N\u0017mHo\t|\u0013\u00EAc\u001D\u00A5\u00C7D_s\u0082\u0017V"
0470: + "\u0083\u00F4\u00CD\u00C6j\u0097p\u00BE\u0002\u0088\u00B3\u00CD"
0471: + "\u00CFrn]\u00D2\u00F3 \u0093`yE\u009B\u0080\u00A5\u00BE`\u00E2"
0472: + "\u00DB\u00A9\u00C21\u0001\u00EB\u00A51\\\"NB\u00F2\u001C\\\u0015"
0473: + "r\u00F6r\u001B,\u001A\u00D2\u00FF\u00F3\u008C%@N2N\u00D7/@g\u00B7"
0474: + "\u00FD\u0005#\u0013\u008E\\\u00A3\u00BCx\u00DC\u000F\u00D6nu"
0475: + "\u0092\"\u0083xMk\u0017X\u00EB\u00B1nD\tO\u0085?H\u001D\u0087"
0476: + "\u00FC\u00FE\u00AE{w\u00B5\u00FFv\u008C#\u0002\u00BF\u00AA\u00F4"
0477: + "uV_F\u00B0*+\t(\u0001=8\u00F5\u00F7\u000C\u00A8\u001F6R\u00AF"
0478: + "J\u008Af\u00D5\u00E7\u00C0\u00DF;\u0008t\u0095\u0005Q\u0010\u001B"
0479: + "Z\u00D7\u00A8\u00F6\u001E\u00D5\u00ADl\u00F6\u00E4y u\u0081\u0084"
0480: + "\u00D0\u00CE\u00FAe\u0088\u00F7\u00BEXJ\u0004h&\u000F\u00F6\u00F8"
0481: + "\u00F3\u00A0\u009C\u007FpSF\u00AB\u00A0\\\u00E9l(\u00E1v\u00ED"
0482: + "\u00A3k\u00AC0\u007F7h)\u00D2\u00856\u000F\u00A9\u0017\u00E3"
0483: + "\u00FE*$\u00B7\u0097g\u00F5\u00A9k \u00D6\u00CD%\u0095h\u00FF"
0484: + "\u001E\u00BFuUD,\u00F1\u009F\u0006\u00BE\u00F9\u00E0e\u009A\u00EE"
0485: + "\u00B9I\u001D4\u0001\u0007\u0018\u00BB0\u00CA\u00B8\u00E8\"\u00FE"
0486: + "\u0015\u0088W\t\u0083u\u000EbI\u00DAb~U^v\u00FF\u00A8\u00B1S"
0487: + "EFmG\u00DE\u0008\u00EF\u00E9\u00E7\u00D4",
0488: sS6 = "\u00F6\u00FA\u008F\u009D,\u00ACl\u00E1L\u00A3Hg\u00E23\u007F"
0489: + "|\u0095\u00DB\u0008\u00E7\u0001hC\u00B4\u00EC\u00ED\\\u00BC2"
0490: + "US\u00AC\u00BF\u009F\t`\u00DF\u00A1\u00E2\u00ED\u0083\u00F0W"
0491: + "\u009Dc\u00ED\u0086\u00B9\u001A\u00B6\u00A6\u00B8\u00DE^\u00BE"
0492: + "9\u00F3\u008F\u00F72\u0089\u0089\u00B183\u00F1Ia\u00C0\u0019"
0493: + "7\u00BD\u00F5\u0006\u00C6\u00DA\u00E4b^~\u00A3\u0008\u00EA\u0099"
0494: + "N#\u00E3<y\u00CB\u00D7\u00CCH\u00A1Cg\u00A3\u0014\u0096\u0019"
0495: + "\u00FE\u00C9K\u00D5\u00A1\u0014\u0017J\u00EA\u00A0\u0018f\u00A0"
0496: + "\u0084\u00DB-\t\u00A8Ho\u00A8\u0088aJ)\u0000\u00AF\u0098\u0001"
0497: + "fY\u0091\u00E1\u0099(c\u00C8\u00F3\u000C`.x\u00EF<\u00D0\u00D5"
0498: + "\u00192\u00CF\u000F\u00EC\u0014\u00F7\u00CA\u0007\u00D2\u00D0"
0499: + "\u00A8 r\u00FDA\u0019~\u0093\u0005\u00A6\u00B0\u00E8k\u00E3\u00DA"
0500: + "t\u00BE\u00D3\u00CD7-\u00A5<L\u007FDH\u00DA\u00B5\u00D4@m\u00BA"
0501: + "\u000E\u00C3\u00089\u0019\u00A7\u009F\u00BA\u00EE\u00D9I\u00DB"
0502: + "\u00CF\u00B0Ng\u000CS\\=\u009C\u0001d\u00BD\u00B9A,\u000Ecj\u00BA"
0503: + "}\u00D9\u00CD\u00EAos\u0088\u00E7\u000B\u00C7b5\u00F2\u009A\u00DB"
0504: + "\\L\u00DD\u008D\u00F0\u00D4\u008D\u008C\u00B8\u0081S\u00E2\u0008"
0505: + "\u00A1\u0098f\u001A\u00E2\u00EA\u00C8(L\u00AF\u0089\u00AA\u0092"
0506: + "\u0082#\u00934\u00BES;:!\u00BF\u0016CK\u00E3\u009A\u00EA9\u0006"
0507: + "\u00EF\u00E8\u00C3n\u00F8\u0090\u00CD\u00D9\u0080\"m\u00AE\u00C3"
0508: + "@\u00A4\u00A3\u00DF~\u009C\t\u00A6\u0094\u00A8\u0007[|^\u00CC"
0509: + "\"\u001D\u00B3\u00A6\u009Ai\u00A0/h\u0081\u008AT\u00CE\u00B2"
0510: + ")oS\u00C0\u0084:\u00FE\u00896U%\u00BF\u00E6\u008A\u00B4b\u008A"
0511: + "\u00BC\u00CF\".\u00BF%\u00ACoH\u00A9\u00A9\u0093\u0087S\u00BD"
0512: + "\u00DBe\u00E7o\u00FB\u00E7\u00E9g\u00FDx\u000B\u00A95c\u008E"
0513: + "4+\u00C1\u00E8\u00A1\u001B\u00E9I\u0080t\r\u00C8\u0008}\u00FC"
0514: + "\u008D\u00E4\u00BF\u0099\u00A1\u0011\u0001\u00A0\u007F\u00D3"
0515: + "yu\u00DAZ&\u00C0\u00E8\u001F\u0099O\u0095(\u00CD\u0089\u00FD"
0516: + "3\u009F\u00ED\u00B8x4\u00BF_\u0004Em\"%\u0086\u0098\u00C9\u00C4"
0517: + "\u00C8;-\u00C1V\u00BEOb\u008D\u00AAW\u00F5^\u00C5\u00E2\"\n\u00BE"
0518: + "\u00D2\u0091n\u00BFN\u00C7[\u0095$\u00F2\u00C3\u00C0B\u00D1]"
0519: + "\u0099\u00CD\r\u007F\u00A0{n'\u00FF\u00A8\u00DC\u008A\u00F0s"
0520: + "E\u00C1\u0006\u00F4\u001E#/5\u0016#\u0086\u00E6\u00EA\u0089&"
0521: + "33\u00B0\u0094\u0015~\u00C6\u00F27+t\u00AFi%s\u00E4\u00E9\u00A9"
0522: + "\u00D8H\u00F3\u0016\u0002\u0089:b\u00EF\u001D\u00A7\u0087\u00E2"
0523: + "8\u00F3\u00A5\u00F6vt6HS \u0095\u0010cEvi\u008D\u00B6\u00FA\u00D4"
0524: + "\u0007Y*\u00F9P6\u00F75#L\u00FBn\u0087}\u00A4\u00CE\u00C0l\u0015"
0525: + "-\u00AA\u00CB\u0003\u0096\u00A8\u00C5\r\u00FE]\u00FC\u00D7\u0007"
0526: + "\u00AB\t!\u00C4/\u0089\u00DF\u00F0\u00BB_\u00E2\u00BExD\u008F"
0527: + "O3uF\u0013\u00C9+\u0005\u00D0\u008DH\u00B9\u00D5\u0085\u00DC"
0528: + "\u0004\u0094A\u00C8\t\u008F\u009B}\u00ED\u00E7\u0086\u00C3\u009A"
0529: + "3sBA\u0000\u0005j\t\u0017Q\u000E\u00F3\u00C8\u00A6\u0089\u0000"
0530: + "r\u00D6( v\u0082\u00A9\u00A9\u00F7\u00BE\u00BF2g\u009D\u00D4"
0531: + "[[u\u00B3S\u00FD\u0000\u00CB\u00B0\u00E3X\u0083\u000F\"\n\u001F"
0532: + "\u008F\u00B2\u0014\u00D3r\u00CF\u0008\u00CC<J\u0013\u008C\u00F6"
0533: + "1f\u0006\u001C\u0087\u00BE\u0088\u00C9\u008F\u0088`b\u00E3\u0097"
0534: + "G\u00CF\u008Ez\u00B6\u00C8R\u0083<\u00C2\u00AC\u00FB?\u00C0i"
0535: + "vN\u008F\u0002Rd\u00D81M\u00DA8p\u00E3\u001EfTY\u00C1\t\u0008"
0536: + "\u00F0Q0!\u00A5l[h\u00B7\u0082/\u008A\u00A00\u0007\u00CD>tq\u009E"
0537: + "\u00EF\u00DC\u0087&\u0081\u00073@\u00D4~C/\u00D9\u000C^\u00C2"
0538: + "A\u0088\t(l\u00F5\u0092\u00D8\u0091\u0008\u00A90\u00F6\u0095"
0539: + "~\u00F3\u0005\u00B7\u00FB\u00FF\u00BD\u00C2f\u00E9oo\u00E4\u00AC"
0540: + "\u0098\u00B1s\u00EC\u00C0\u00BC`\u00B4*\u00954\u0098\u00DA\u00FB"
0541: + "\u00A1\u00AE\u0012-K\u00D76\u000F%\u00FA\u00AB\u00A4\u00F3\u00FC"
0542: + "\u00EB\u00E2\u0096\u0091#%\u007F\u000C=\u0093H\u00AFI6\u0014"
0543: + "\u0000\u00BC\u00E8\u0081oJ8\u0014\u00F2\u0000\u00A3\u00F9@C\u009C"
0544: + "zT\u00C2\u00BCpOW\u00DAA\u00E7\u00F9\u00C2Z\u00D3:T\u00F4\u00A0"
0545: + "\u0084\u00B1\u007FU\u0005Y5|\u00BE\u00ED\u00BD\u0015\u00C8\u007F"
0546: + "\u0097\u00C5\u00AB\u00BAZ\u00C7\u00B5\u00B6\u00F6\u00DE\u00AF"
0547: + ":G\u009C:S\u0002\u00DA%e=~jT&\u008DIQ\u00A4w\u00EAP\u0017\u00D5"
0548: + "[\u00D7\u00D2]\u0088D\u0013lv\u0004\u0004\u00A8\u00C8\u00B8\u00E5"
0549: + "\u00A1!\u00B8\u001A\u0092\u008A`\u00EDXi\u0097\u00C5[\u0096\u00EA"
0550: + "\u00EC\u0099\u001B)\u0093Y\u0013\u0001\u00FD\u00B7\u00F1\u0008"
0551: + "\u008E\u008D\u00FA\u009A\u00B6\u00F6\u00F5;L\u00BF\u009FJ]\u00E3"
0552: + "\u00AB\u00E6\u0005\u001D5\u00A0\u00E1\u00D8U\u00D3kL\u00F1\u00F5"
0553: + "D\u00ED\u00EB\u00B0\u00E95$\u00BE\u00BB\u008F\u00BD\u00A2\u00D7"
0554: + "b\u00CFI\u00C9/T8\u00B5\u00F31q(\u00A4TH9)\u0005\u00A6[\u001D"
0555: + "\u00B8\u0085\u001C\u0097\u00BD\u00D6u\u00CF/",
0556: sS7 = "\u0085\u00E0@\u00193+\u00F5gf-\u00BF\u00FF\u00CF\u00C6V\u0093"
0557: + "*\u008D\u007Fo\u00AB\u009B\u00C9\u0012\u00DE`\u0008\u00A1 (\u00DA"
0558: + "\u001F\u0002'\u00BC\u00E7Md)\u0016\u0018\u00FA\u00C3\u0000P\u00F1"
0559: + "\u008B\u0082,\u00B2\u00CB\u0011\u00B22\u00E7\\K6\u0095\u00F2"
0560: + "\u00B2\u0087\u0007\u00DE\u00A0_\u00BC\u00F6\u00CDA\u0081\u00E9"
0561: + "\u00E1P!\u000C\u00E2N\u00F1\u00BD\u00B1h\u00C3\u0081\u00FD\u00E4"
0562: + "\u00E7\u0089\\y\u00B0\u00D8\u001E\u008B\u00FDCMIP\u00018\u00BE"
0563: + "CA\u0091<\u00EE\u001D\u0092\u00A7\u009C?\u0008\u0097f\u00BE\u00BA"
0564: + "\u00EE\u00AD\u00F4\u0012\u0086\u00BE\u00CF\u00B6\u00EA\u00CB"
0565: + "\u0019&`\u00C2\u0000ue\u00BD\u00E4d$\u001Fz\u0082H\u00DC\u00A9"
0566: + "\u00C3\u00B3\u00ADf(\u0013`\u0086\u000B\u00D8\u00DF\u00A85m\u001C"
0567: + "\u00F2\u0010w\u0089\u00BE\u00B3\u00B2\u00E9\u00CE\u0005\u0002"
0568: + "\u00AA\u008F\u000B\u00C05\u001E\u0016k\u00F5*\u00EB\u0012\u00FF"
0569: + "\u0082\u00E3Hi\u0011\u00D3Mu\u0016N{:\u00FF_Cg\u001B\u009C\u00F6"
0570: + "\u00E07I\u0081\u00AC\u00833Bf\u00CE\u008C\u0093A\u00B7\u00D0"
0571: + "\u00D8T\u00C0\u00CB:l\u0088G\u00BC()G%\u00BA7\u00A6j\u00D2+z"
0572: + "\u00D6\u001F\u001E\u000C\\\u00BA\u00FAD7\u00F1\u0007\u00B6\u00E7"
0573: + "\u0099bB\u00D2\u00D8\u0016\n\u0096\u0012\u0088\u00E1\u00A5\u00C0"
0574: + "n\u0013t\u009Egr\u00FC\u0008\u001A\u00B1\u00D19\u00F7\u00F9X"
0575: + "7E\u00CF\u0019\u00DFX\u00BE\u00C3\u00F7V\u00C0n\u00BA0\u0007"
0576: + "!\u001B$E\u00C2\u0088)\u00C9^1\u007F\u00BC\u008E\u00C5\u0011"
0577: + "8\u00BCF\u00E9\u00C6\u00E6\u00FA\u0014\u00BA\u00E8XJ\u00ADN\u00BC"
0578: + "FF\u008FP\u008Bx)C_\u00F1$\u0018;\u0082\u001D\u00BA\u009F\u00AF"
0579: + "\u00F6\u000F\u00F4\u00EA,Nm\u0016\u00E3\u0092d\u0092TJ\u008B"
0580: + "\u0000\u009BO\u00C3\u00AB\u00A6\u008C\u00ED\u009A\u00C9ox\u0006"
0581: + "\u00A5\u00B7\u009A\u00B2\u0085nn\u001A\u00EC<\u00A9\u00BE\u0083"
0582: + "\u0086\u0088\u000E\u0008\u0004\u00E9U\u00F1\u00BEV\u00E7\u00E5"
0583: + "6;\u00B3\u00A1\u00F2]\u00F7\u00DE\u00BB\u0085a\u00FE\u0003<\u0016"
0584: + "tb3<\u0003L(\u00DAm\u000Cty\u00AA\u00C5l<\u00E4\u00E1\u00ADQ"
0585: + "\u00F0\u00C8\u0002\u0098\u00F8\u00F3Z\u0016&\u00A4\u009F\u00EE"
0586: + "\u00D8+)\u001D8/\u00E3\u000CO\u00B9\u009A\u00BB2Wx>\u00C6\u00D9"
0587: + "{nw\u00A6\u00A9\u00CBe\u008B\\\u00D4R0\u00C7+\u00D1@\u008B`\u00C0"
0588: + ">\u00B7\u00B9\u0006\u008Dx\u00A37T\u00F4\u00F40\u00C8}\u00C8"
0589: + "\u00A7\u0013\u0002\u00B9m\u008C2\u00EB\u00D4\u00E7\u00BE\u00BE"
0590: + "\u008B\u009D-yy\u00FB\u0006\u00E7\"S\u0008\u008Bu\u00CFw\u0011"
0591: + "\u00EF\u008D\u00A4\u00E0\u0083\u00C8X\u008DkxoZc\u0017\u00A6"
0592: + "\u00FA\\\u00F7\u00A0]\u00DA\u00003\u00F2\u008E\u00BF\u00B0\u00F5"
0593: + "\u00B9\u00C3\u0010\u00A0\u00EA\u00C2\u0080\u0008\u00B9vz\u00A3"
0594: + "\u00D9\u00D2\u00B0y\u00D3B\u0017\u0002\u001Aq\u008D\u009A\u00C6"
0595: + "3j'\u0011\u00FD`C\u0080P\u00E3\u0006\u0099\u0008\u00A8=\u007F"
0596: + "\u00ED\u00C4\u0082m+\u00EFN\u00EB\u0084vH\u008D\u00CF%6\u00C9"
0597: + "\u00D5f(\u00E7NA\u00C2a\n\u00CA=I\u00A9\u00CF\u00BA\u00E3\u00B9"
0598: + "\u00DF\u00B6_\u008D\u00E6\u0092\u00AE\u00AFd:\u00C7\u00D5\u00E6"
0599: + "\u009E\u00A8\u0005\t\u00F2+\u0001}\u00A4\u0017?p\u00DD\u001E"
0600: + "\u0016\u00C3\u0015\u00E0\u00D7\u00F9P\u00B1\u00B8\u0087+\u009F"
0601: + "O\u00D5bZ\u00BA\u0082j\u0001yb.\u00C0\u001B\u009C\u0015H\u008A"
0602: + "\u00A9\u00D7\u0016\u00E7@@\u0005Z,\u0093\u00D2\u009A\"\u00E3"
0603: + "-\u00BF\u009A\u0005\u0087E\u00B94S\u00DC\u001E\u00D6\u0099)n"
0604: + "Il\u00FFo\u001C\u009FI\u0086\u00DF\u00E2\u00ED\u0007\u00B8rB"
0605: + "\u00D1\u0019\u00DE~\u00AE\u0005>V\u001A\u0015\u00ADo\u008Cfb"
0606: + "l\u001CqT\u00C2L\u00EA\u0008+*\u0093\u00EB)9\u0017\u00DC\u00B0"
0607: + "\u00F0X\u00D4\u00F2\u00AE\u009E\u00A2\u0094\u00FBR\u00CFVL\u0098"
0608: + "\u0083\u00FEf.\u00C4\u0005\u0081v9S\u00C3\u0001\u00D6i.\u00D3"
0609: + "\u00A0\u00C1\u0008\u00A1\u00E7\u0016\u000E\u00E4\u00F2\u00DF"
0610: + "\u00A6i>\u00D2\u0085t\u0090F\u0098L+\u000E\u00DDOuvV]93x\u00A1"
0611: + "2#O=2\u001C]\u00C3\u00F5\u00E1\u0094K&\u0093\u0001\u00C7\u009F"
0612: + "\u0002/<\u0099~~^O\u0095\u0004?\u00FA\u00FB\u00BDv\u00F7\u00AD"
0613: + "\u000E)f\u0093\u00F4=\u001F\u00CEo\u00C6\u001EE\u00BE\u00D3\u00B5"
0614: + "\u00AB4\u00F7+\u00F9\u00B7\u001B\u00044\u00C0Nr\u00B5gU\u0092"
0615: + "\u00A3=\u00B5\"\u0093\u0001\u00CF\u00D2\u00A8\u007F`\u00AE\u00B7"
0616: + "g\u0018\u00148k0\u00BC\u00C3=8\u00A0\u00C0}\u00FD\u0016\u0006"
0617: + "\u00F2\u00C3cQ\u009BX\u009D\u00D3\u0090Ty\u00F8\u00E6\u001C\u00B8"
0618: + "\u00D6G\u0097\u00FDa\u00A9\u00EAwY\u00F4-WS\u009DV\u009AX\u00CF"
0619: + "\u00E8Nc\u00ADF.\u001Bxe\u0080\u00F8~\u00F3\u0081y\u0014\u0091"
0620: + "\u00DAU\u00F4@\u00A20\u00F3\u00D1\u0098\u008F5\u00B6\u00E3\u0018"
0621: + "\u00D2?\u00FAP\u00BC=@\u00F0!\u00C3\u00C0\u00BD\u00AEIX\u00C2"
0622: + "LQ\u008F6\u00B2\u0084\u00B1\u00D3p\u000F\u00ED\u00CE\u0083\u0087"
0623: + "\u008D\u00DA\u00DA\u00F2\u00A2y\u00C7\u0094\u00E0\u001B\u00E8"
0624: + "\u0090qoK\u0095K\u008A\u00A3",
0625: sS8 = "\u00E2\u00160\r\u00BB\u00DD\u00FF\u00FC\u00A7\u00EB\u00DA\u00BD"
0626: + "5d\u0080\u0095w\u0089\u00F8\u00B7\u00E6\u00C1\u0012\u001B\u000E"
0627: + "$\u0016\u0000\u0005,\u00E8\u00B5\u0011\u00A9\u00CF\u00B0\u00E5"
0628: + "\u0095/\u0011\u00EC\u00E7\u0099\n\u0093\u0086\u00D1t*B\u0093"
0629: + "\u001Cv\u00E3\u0081\u0011\u00B1-\u00EF:7\u00DD\u00DD\u00FC\u00DE"
0630: + "\u009A\u00DE\u00B1\n\u000C\u00C3,\u00BE\u0019p)\u0084\u00A0\t"
0631: + "@\u00BB$:\u000F\u00B4\u00D17\u00CF\u00B4Ny\u00F0\u0004\u009E"
0632: + "\u00ED\u00FD\u000B\u0015\u00A1]H\r1h\u008B\u00BB\u00DEZf\u009D"
0633: + "\u00EDB\u00C7\u00EC\u00E81?\u008F\u0095\u00E7r\u00DF\u0019\u001B"
0634: + "u\u00803\r\u0094\u0007BQ\\}\u00CD\u00FA\u00AB\u00BEmc\u00AA@"
0635: + "!d\u00B3\u0001\u00D4\n\u0002\u00E7\u00D1\u00CASW\u001D\u00AE"
0636: + "z1\u0082\u00A2\u0012\u00A8\u00DD\u00EC\u00FD\u00AA3]\u0017oC"
0637: + "\u00E8q\u00FBF\u00D48\u0012\u0090\"\u00CE\u0094\u009A\u00D4\u00B8"
0638: + "Gi\u00AD\u0096[\u00D8b\u0082\u00F3\u00D0Uf\u00FB\u0097g\u0015"
0639: + "\u00B8\u000BN\u001D[G\u00A0L\u00FD\u00E0o\u00C2\u008E\u00C4\u00B8"
0640: + "W\u00E8rndzx\u00FC\u0099\u0086]D`\u008B\u00D5\u0093l \u000E\u0003"
0641: + "9\u00DC_\u00F6]\u000B\u0000\u00A3\u00AEc\u00AF\u00F2~\u008B\u00D6"
0642: + "2p\u0010\u008C\u000C\u00BB\u00D3PI)\u0098\u00DF\u0004\u0098\u000C"
0643: + "\u00F4*\u009Bm\u00F4\u0091\u009E~\u00DDS\u0006\u0091\u0085HX"
0644: + "\u00CB~\u0007;t\u00EF.R/\u00FF\u00B1\u00D2G\u0008\u00CC\u001C"
0645: + "~'\u00CD\u00A4\u00EB![<\u00F1\u00D2\u00E2\u0019\u00B4z8BOv\u0018"
0646: + "5\u0085`9\u009D\u0017\u00DE\u00E7'\u00EB5\u00E6\u00C9\u00AF\u00F6"
0647: + "{6\u00BA\u00F5\u00B8\t\u00C4g\u00CD\u00C1\u0089\u0010\u00B1\u00E1"
0648: + "\u001D\u00BF{\u0006\u00CD\u001A\u00F8qp\u00C6\u0008-^3T\u00D4"
0649: + "\u00DEIZd\u00C6\u00D0\u0006\u00BC\u00C0\u00C6,=\u00D0\r\u00B3"
0650: + "p\u008F\u008F4w\u00D5\u001BB&Ob\u000F$\u00B8\u00D2\u00BF\u0015"
0651: + "\u00C1\u00B7\u009EF\u00A5%d\u00F8\u00D7\u00E5N>7\u0081`x\u0095"
0652: + "\u00CD\u00A5\u0085\u009C\u0015\u00A5\u00E6E\u0097\u0088\u00C3"
0653: + "{\u00C7_\u00DB\u0007\u00BA\u000C\u0006v\u00A3\u00AB\u007F\"\u009B"
0654: + "\u001E1\u0084.{$%\u009F\u00D7\u00F8\u00BE\u00F4r\u0083_\u00FC"
0655: + "\u00B8m\u00F4\u00C1\u00F2\u0096\u00F5\u00B1\u0095\u00FD\n\u00F0"
0656: + "\u00FC\u00B0\u00FE\u0013L\u00E2Pm=O\u009B\u0012\u00EA\u00F2\u0015"
0657: + "\u00F2%\u00A2#so\u009F\u00B4\u00C4(%\u00D0Iy4\u00C7\u0013\u00F8"
0658: + "\u00C4a\u0081\u0087\u00EAzn\u0098|\u00D1n\u00FC\u00146\u0087"
0659: + "l\u00F1TA\u0007\u00BE\u00DE\u00EE\u0014V\u00E9\u00AF'\u00A0J"
0660: + "\u00A4A<\u00F7\u00C8\u0099\u0092\u00EC\u00BA\u00E6\u00DDg\u0001"
0661: + "m\u0015\u0016\u0082\u00EB\u00A8B\u00EE\u00DF\u00FD\u00BA`\u00B4"
0662: + "\u00F1\u0090{u \u00E3\u0003\u000F$\u00D8\u00C2\u009E\u00E19g"
0663: + ";\u00EF\u00A6?\u00B8q\u00870T\u00B6\u00F2\u00CF;\u009F2dB\u00CB"
0664: + "\u0015\u00A4\u00CC\u00B0\u001AE\u0004\u00F1\u00E4}\u008D\u0084"
0665: + "J\u001B\u00E5\u00BA\u00E7\u00DF\u00DCB\u00CB\u00DAp\u00CD}\u00AE"
0666: + "\nW\u00E8[z\u00D5?Z\u00F6 \u00CFM\u008C\u00CE\u00A4\u00D4(y\u00D1"
0667: + "0\u00A44\u0086\u00EB\u00FB3\u00D3\u00CD\u00DCw\u0085;S7\u00EF"
0668: + "\u00FC\u00B5\u00C5\u0006\u0087x\u00E5\u0080\u00B3\u00E6Nh\u00B8"
0669: + "\u00F4\u00C5\u00C8\u00B3~\r\u0080\u009E\u00A29\u008F\u00EB|\u0013"
0670: + "*O\u0094C\u00B7\u0095\u000E/\u00EE}\u001C\"6\u0013\u00BD\u00DD"
0671: + "\u0006\u00CA\u00A27\u00DF\u0093+\u00C4$\u0082\u0089\u00AC\u00F3"
0672: + "\u00EB\u00C3W\u0015\u00F6\u00B7\u00EF4x\u00DD\u00F2gao\u00C1"
0673: + "H\u00CB\u00E4\u0090R\u0081^^A\u000F\u00AB\u00B4\u008A$e.\u00DA"
0674: + "\u007F\u00A4\u00E8{@\u00E4\u00E9\u008E\u00A0\u0084X\u0089\u00E9"
0675: + "\u00E1\u00EF\u00D3\u0090\u00FC\u00DD\u0007\u00D3[\u00DBHV\u0094"
0676: + "8\u00D7\u00E5\u00B2Wr\u0001\u0001s\u000E\u00DE\u00BC[d1\u0013"
0677: + "\u0094\u0091~OP</\u00BAdo\u0012\u0082u#\u00D2J\u00E0w\u0096\u0095"
0678: + "\u00F9\u00C1z\u008Fz[!!\u00D1\u0087\u00B8\u0096)&:M\u00BAQ\u000C"
0679: + "\u00DF\u0081\u00F4|\u009F\u00AD\u0011c\u00ED\u00EA{Ye\u001A\u0000"
0680: + "rn\u0011@0\u0092\u0000\u00DAmwJ\u000C\u00DDa\u00AD\u001FF\u0003"
0681: + "`[\u00DF\u00B0\u009E\u00ED\u00C3d\"\u00EB\u00E6\u00A8\u00CE\u00E7"
0682: + "\u00D2\u008A\u00A0\u00E76\u00A0Ud\u00A6\u00B9\u0010\u00852\t"
0683: + "\u00C7\u00EB\u008F7-\u00E7\u0005\u00CA\u0089QW\u000F\u00DF\t"
0684: + "\u0082+\u00BDi\u001Al\u00AA\u0012\u00E4\u00F2\u0087E\u001C\u000F"
0685: + "\u00E0\u00F6\u00A2z:\u00DAH\u0019L\u00F1vO\rw\u001C+g\u00CD\u00B1"
0686: + "V5\r\u0083\u0084Y8\u00FA\u000FB9\u009E\u00F36\u0099{\u0007\u000E"
0687: + "\u0084\t=J\u00A9>a\u0083`\u00D8{\u001F\u00A9\u008B\u000C\u0011"
0688: + "I8,\u00E9v%\u00A5\u0006\u0014\u00D1\u00B7\u000E%$K\u000Cv\u0083"
0689: + "GX\u009E\u008D\u0082\r Y\u00D1\u00A4f\u00BB\u001E\u00F8\u00DA"
0690: + "\n\u0082\u0004\u00F1\u00910\u00BAnN\u00C0\u0099&Qd\u001E\u00E7"
0691: + "#\rP\u00B2\u00AD\u0080\u00EA\u00EEh\u0001\u008D\u00B2\u00A2\u0083"
0692: + "\u00EA\u008B\u00F5\u009E";
0693:
0694: /** 8 S-boxes */
0695: private static final int[] S0, S1, S2, S3, S4, S5, S6, S7, S8;
0696:
0697: /**
0698: * Expand a String of compressed S-box data and return an
0699: * S-box with uncompressed data.
0700: */
0701: private static int[] expand(String in) {
0702: int[] S = new int[256];
0703: for (int i = 0, j = 0; i < S.length; i++)
0704: S[i] = (in.charAt(j++) << 24) | (in.charAt(j++) << 16)
0705: | (in.charAt(j++) << 8) | (in.charAt(j++));
0706: return S;
0707: }
0708:
0709: /**
0710: * Initialize the S-boxes by expanding them from the compressed data.
0711: * Zero out the references (sS*) to the compressed data as we no
0712: * longer need them.
0713: */
0714: static {
0715: S0 = expand(sS0);
0716: sS0 = null;
0717: S1 = expand(sS1);
0718: sS1 = null;
0719: S2 = expand(sS2);
0720: sS2 = null;
0721: S3 = expand(sS3);
0722: sS3 = null;
0723: S4 = expand(sS4);
0724: sS4 = null;
0725: S5 = expand(sS5);
0726: sS5 = null;
0727: S6 = expand(sS6);
0728: sS6 = null;
0729: S7 = expand(sS7);
0730: sS7 = null;
0731: S8 = expand(sS8);
0732: sS8 = null;
0733: }
0734:
0735: // Instance variables
0736: //............................................................................
0737:
0738: /** We are in decrypt mode */
0739: private boolean decrypt;
0740:
0741: /** Number of rounds (depends on key length) */
0742: private int rounds = DEFAULT_NOF_ROUNDS;
0743:
0744: /** Masking session keys. */
0745: private int Km0, Km1, Km2, Km3, Km4, Km5, Km6, Km7, Km8, Km9, Km10,
0746: Km11, Km12, Km13, Km14, Km15;
0747:
0748: /** Rotation session keys. */
0749: private int Kr0, Kr1, Kr2, Kr3, Kr4, Kr5, Kr6, Kr7, Kr8, Kr9, Kr10,
0750: Kr11, Kr12, Kr13, Kr14, Kr15;
0751:
0752: // Constructors
0753: //............................................................................
0754:
0755: public CAST5() {
0756: super (BLOCK_SIZE);
0757: }
0758:
0759: // Implementation of abstract methods
0760: //............................................................................
0761:
0762: /** Initializes this cipher using the specified key. */
0763: protected void coreInit(Key key, boolean decrypt)
0764: throws InvalidKeyException {
0765: this .decrypt = decrypt;
0766: makeKey(key);
0767: }
0768:
0769: /** Encrypt or decrypt a single data block */
0770: protected void coreCrypt(byte[] in, int inOffset, byte[] out,
0771: int outOffset) {
0772: if (decrypt)
0773: blockDecrypt(in, inOffset, out, outOffset);
0774: else
0775: blockEncrypt(in, inOffset, out, outOffset);
0776: }
0777:
0778: // Private parts
0779: //............................................................................
0780:
0781: /**
0782: * Expands a user key to a working CAST5 128-bit key --by
0783: * padding it with 0x00 if it's shorter than 16 bytes--
0784: * and generates the masking and rotation keypairs for
0785: * the block cipher.
0786: *
0787: * @param key The user key object.
0788: * @exception KeyException
0789: * when one of the following occurs:<ul>
0790: * <li>The user key object is null;
0791: * <li>The decoded byte array form of the user key is
0792: * zero long;
0793: * <li>The decoded user key is shorter than 40 bits or
0794: * longer than 128 bits.</ul>
0795: */
0796: private void makeKey(Key key) throws InvalidKeyException {
0797: byte[] userkey = key.getEncoded();
0798: if (userkey == null)
0799: throw new InvalidKeyException("Null user key");
0800:
0801: int len = userkey.length;
0802: if (len < 5 || len > 16)
0803: throw new InvalidKeyException("Invalid user key length");
0804:
0805: rounds = (len < 11) ? MIN_NOF_ROUNDS : MAX_NOF_ROUNDS;
0806:
0807: byte[] kk = new byte[16];
0808: System.arraycopy(userkey, 0, kk, 0, len);
0809:
0810: int x0x1x2x3 = (kk[0] & 0xFF) << 24 | (kk[1] & 0xFF) << 16
0811: | (kk[2] & 0xFF) << 8 | (kk[3] & 0xFF), x4x5x6x7 = (kk[4] & 0xFF) << 24
0812: | (kk[5] & 0xFF) << 16
0813: | (kk[6] & 0xFF) << 8
0814: | (kk[7] & 0xFF), x8x9xAxB = (kk[8] & 0xFF) << 24
0815: | (kk[9] & 0xFF) << 16 | (kk[10] & 0xFF) << 8
0816: | (kk[11] & 0xFF), xCxDxExF = (kk[12] & 0xFF) << 24
0817: | (kk[13] & 0xFF) << 16 | (kk[14] & 0xFF) << 8
0818: | (kk[15] & 0xFF), z0z1z2z3, z4z5z6z7, z8z9zAzB, zCzDzEzF, z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, zA, zB, zC, zD, zE, zF, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xA, xB, xC, xD, xE, xF;
0819: int[] b;
0820:
0821: b = unscramble(x0x1x2x3);
0822: x0 = b[0];
0823: x1 = b[1];
0824: x2 = b[2];
0825: x3 = b[3];
0826: b = unscramble(x4x5x6x7);
0827: x4 = b[0];
0828: x5 = b[1];
0829: x6 = b[2];
0830: x7 = b[3];
0831: b = unscramble(x8x9xAxB);
0832: x8 = b[0];
0833: x9 = b[1];
0834: xA = b[2];
0835: xB = b[3];
0836: b = unscramble(xCxDxExF);
0837: xC = b[0];
0838: xD = b[1];
0839: xE = b[2];
0840: xF = b[3];
0841:
0842: z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE]
0843: ^ S7[x8];
0844: b = unscramble(z0z1z2z3);
0845: z0 = b[0];
0846: z1 = b[1];
0847: z2 = b[2];
0848: z3 = b[3];
0849: z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3]
0850: ^ S8[xA];
0851: b = unscramble(z4z5z6z7);
0852: z4 = b[0];
0853: z5 = b[1];
0854: z6 = b[2];
0855: z7 = b[3];
0856: z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4]
0857: ^ S5[x9];
0858: b = unscramble(z8z9zAzB);
0859: z8 = b[0];
0860: z9 = b[1];
0861: zA = b[2];
0862: zB = b[3];
0863: zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8]
0864: ^ S6[xB];
0865: b = unscramble(zCzDzEzF);
0866: zC = b[0];
0867: zD = b[1];
0868: zE = b[2];
0869: zF = b[3];
0870:
0871: Km0 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2];
0872: Km1 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6];
0873: Km2 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9];
0874: Km3 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC];
0875:
0876: x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6]
0877: ^ S7[z0];
0878: b = unscramble(x0x1x2x3);
0879: x0 = b[0];
0880: x1 = b[1];
0881: x2 = b[2];
0882: x3 = b[3];
0883: x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3]
0884: ^ S8[z2];
0885: b = unscramble(x4x5x6x7);
0886: x4 = b[0];
0887: x5 = b[1];
0888: x6 = b[2];
0889: x7 = b[3];
0890: x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4]
0891: ^ S5[z1];
0892: b = unscramble(x8x9xAxB);
0893: x8 = b[0];
0894: x9 = b[1];
0895: xA = b[2];
0896: xB = b[3];
0897: xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8]
0898: ^ S6[z3];
0899: b = unscramble(xCxDxExF);
0900: xC = b[0];
0901: xD = b[1];
0902: xE = b[2];
0903: xF = b[3];
0904:
0905: Km4 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8];
0906: Km5 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD];
0907: Km6 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3];
0908: Km7 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7];
0909:
0910: z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE]
0911: ^ S7[x8];
0912: b = unscramble(z0z1z2z3);
0913: z0 = b[0];
0914: z1 = b[1];
0915: z2 = b[2];
0916: z3 = b[3];
0917: z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3]
0918: ^ S8[xA];
0919: b = unscramble(z4z5z6z7);
0920: z4 = b[0];
0921: z5 = b[1];
0922: z6 = b[2];
0923: z7 = b[3];
0924: z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4]
0925: ^ S5[x9];
0926: b = unscramble(z8z9zAzB);
0927: z8 = b[0];
0928: z9 = b[1];
0929: zA = b[2];
0930: zB = b[3];
0931: zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8]
0932: ^ S6[xB];
0933: b = unscramble(zCzDzEzF);
0934: zC = b[0];
0935: zD = b[1];
0936: zE = b[2];
0937: zF = b[3];
0938:
0939: Km8 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9];
0940: Km9 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC];
0941: Km10 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2];
0942: Km11 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6];
0943:
0944: x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6]
0945: ^ S7[z0];
0946: b = unscramble(x0x1x2x3);
0947: x0 = b[0];
0948: x1 = b[1];
0949: x2 = b[2];
0950: x3 = b[3];
0951: x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3]
0952: ^ S8[z2];
0953: b = unscramble(x4x5x6x7);
0954: x4 = b[0];
0955: x5 = b[1];
0956: x6 = b[2];
0957: x7 = b[3];
0958: x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4]
0959: ^ S5[z1];
0960: b = unscramble(x8x9xAxB);
0961: x8 = b[0];
0962: x9 = b[1];
0963: xA = b[2];
0964: xB = b[3];
0965: xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8]
0966: ^ S6[z3];
0967: b = unscramble(xCxDxExF);
0968: xC = b[0];
0969: xD = b[1];
0970: xE = b[2];
0971: xF = b[3];
0972:
0973: Km12 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3];
0974: Km13 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7];
0975: Km14 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8];
0976: Km15 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD];
0977:
0978: // The remaining half is identical to what is given above, carrying
0979: // on from the last created x0..xF to generate keys K17 - K32. These
0980: // keys will be used as the 'rotation' keys and as such only the five
0981: // least significant bits are to be considered.
0982:
0983: z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE]
0984: ^ S7[x8];
0985: b = unscramble(z0z1z2z3);
0986: z0 = b[0];
0987: z1 = b[1];
0988: z2 = b[2];
0989: z3 = b[3];
0990: z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3]
0991: ^ S8[xA];
0992: b = unscramble(z4z5z6z7);
0993: z4 = b[0];
0994: z5 = b[1];
0995: z6 = b[2];
0996: z7 = b[3];
0997: z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4]
0998: ^ S5[x9];
0999: b = unscramble(z8z9zAzB);
1000: z8 = b[0];
1001: z9 = b[1];
1002: zA = b[2];
1003: zB = b[3];
1004: zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8]
1005: ^ S6[xB];
1006: b = unscramble(zCzDzEzF);
1007: zC = b[0];
1008: zD = b[1];
1009: zE = b[2];
1010: zF = b[3];
1011:
1012: Kr0 = (S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]) & 0x1F;
1013: Kr1 = (S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]) & 0x1F;
1014: Kr2 = (S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]) & 0x1F;
1015: Kr3 = (S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]) & 0x1F;
1016:
1017: x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6]
1018: ^ S7[z0];
1019: b = unscramble(x0x1x2x3);
1020: x0 = b[0];
1021: x1 = b[1];
1022: x2 = b[2];
1023: x3 = b[3];
1024: x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3]
1025: ^ S8[z2];
1026: b = unscramble(x4x5x6x7);
1027: x4 = b[0];
1028: x5 = b[1];
1029: x6 = b[2];
1030: x7 = b[3];
1031: x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4]
1032: ^ S5[z1];
1033: b = unscramble(x8x9xAxB);
1034: x8 = b[0];
1035: x9 = b[1];
1036: xA = b[2];
1037: xB = b[3];
1038: xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8]
1039: ^ S6[z3];
1040: b = unscramble(xCxDxExF);
1041: xC = b[0];
1042: xD = b[1];
1043: xE = b[2];
1044: xF = b[3];
1045:
1046: Kr4 = (S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]) & 0x1F;
1047: Kr5 = (S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]) & 0x1F;
1048: Kr6 = (S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]) & 0x1F;
1049: Kr7 = (S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]) & 0x1F;
1050:
1051: z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE]
1052: ^ S7[x8];
1053: b = unscramble(z0z1z2z3);
1054: z0 = b[0];
1055: z1 = b[1];
1056: z2 = b[2];
1057: z3 = b[3];
1058: z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3]
1059: ^ S8[xA];
1060: b = unscramble(z4z5z6z7);
1061: z4 = b[0];
1062: z5 = b[1];
1063: z6 = b[2];
1064: z7 = b[3];
1065: z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4]
1066: ^ S5[x9];
1067: b = unscramble(z8z9zAzB);
1068: z8 = b[0];
1069: z9 = b[1];
1070: zA = b[2];
1071: zB = b[3];
1072: zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8]
1073: ^ S6[xB];
1074: b = unscramble(zCzDzEzF);
1075: zC = b[0];
1076: zD = b[1];
1077: zE = b[2];
1078: zF = b[3];
1079:
1080: Kr8 = (S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]) & 0x1F;
1081: Kr9 = (S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]) & 0x1F;
1082: Kr10 = (S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]) & 0x1F;
1083: Kr11 = (S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]) & 0x1F;
1084:
1085: x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6]
1086: ^ S7[z0];
1087: b = unscramble(x0x1x2x3);
1088: x0 = b[0];
1089: x1 = b[1];
1090: x2 = b[2];
1091: x3 = b[3];
1092: x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3]
1093: ^ S8[z2];
1094: b = unscramble(x4x5x6x7);
1095: x4 = b[0];
1096: x5 = b[1];
1097: x6 = b[2];
1098: x7 = b[3];
1099: x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4]
1100: ^ S5[z1];
1101: b = unscramble(x8x9xAxB);
1102: x8 = b[0];
1103: x9 = b[1];
1104: xA = b[2];
1105: xB = b[3];
1106: xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8]
1107: ^ S6[z3];
1108: b = unscramble(xCxDxExF);
1109: xC = b[0];
1110: xD = b[1];
1111: xE = b[2];
1112: xF = b[3];
1113:
1114: Kr12 = (S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]) & 0x1F;
1115: Kr13 = (S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]) & 0x1F;
1116: Kr14 = (S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]) & 0x1F;
1117: Kr15 = (S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]) & 0x1F;
1118: }
1119:
1120: /**
1121: * Assuming the input is a 32-bit block organised as: b31b30b29...b0,
1122: * returns an array of 4 Java ints, containing from position 0 onward
1123: * the values: {b31b30b29b28, b27b26b25b24, ... , b3b2b1b0}.
1124: *
1125: * @param x a 32-bit block
1126: * @return an array of 4 ints, each being the contents of an 8-bit
1127: * block from the input.
1128: */
1129: private static final int[] unscramble(int x) {
1130: return new int[] { (x >>> 24) & 0xFF, (x >>> 16) & 0xFF,
1131: (x >>> 8) & 0xFF, x & 0xFF };
1132: }
1133:
1134: /**
1135: * The full encryption algorithm is given in the following four steps.
1136: * <p>
1137: * INPUT: plaintext m1...m64; key K = k1...k128.<br>
1138: * OUTPUT: ciphertext c1...c64.
1139: * <ol>
1140: * <li> (key schedule) Compute 16 pairs of subkeys {Kmi, Kri}
1141: * from a user key (see makeKey() method).
1142: * <li> (L0,R0) <-- (m1...m64). (Split the plaintext into left
1143: * and right 32-bit halves L0 = m1...m32 and R0 = m33...m64.).
1144: * <li> (16 rounds) for i from 1 to 16, compute Li and Ri as
1145: * follows:
1146: * <ul>
1147: * <li> Li = Ri-1;
1148: * <li> Ri = Li-1 ^ F(Ri-1,Kmi,Kri), where F is defined in
1149: * method F() --f is of Type 1, Type 2, or Type 3, depending
1150: * on i, and ^ being the bitwise XOR function.
1151: * </ul>
1152: * <li> c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16
1153: * and concatenate to form the ciphertext.)
1154: * </ol>
1155: * <p>
1156: * Decryption is identical to the encryption algorithm given
1157: * above, except that the rounds (and therefore the subkey pairs)
1158: * are used in reverse order to compute (L0,R0) from (R16,L16).
1159: * <p>
1160: * Looking at the iterations/rounds in pairs we have:
1161: * <pre>
1162: * (1a) Li = Ri-1;
1163: * (1b) Ri = Li-1 ^ Fi(Ri-1);
1164: * (2a) Li+1 = Ri;
1165: * (2b) Ri+1 = Li ^ Fi+1(Ri);
1166: * </pre>
1167: * which by substituting (2a) in (2b) becomes
1168: * <pre>
1169: * (2c) Ri+1 = Li ^ Fi+1(Li+1);
1170: * </pre>
1171: * by substituting (1b) in (2a) and (1a) in (2c), we get:
1172: * <pre>
1173: * (3a) Li+1 = Li-1 ^ Fi(Ri-1);
1174: * (3b) Ri+1 = Ri-1 ^ Fi+1(Li+1);
1175: * </pre>
1176: * Using only one couple of variables L and R, initialised to L0 and
1177: * R0 respectively, the assignments for each pair of rounds become:
1178: * <pre>
1179: * (4a) L ^= Fi(R);
1180: * (4b) R ^= Fi+1(L);
1181: * </pre>
1182: *
1183: * @param in contains the plain-text 64-bit block.
1184: * @param off start index within input where data is considered.
1185: * @param out will contain the cipher-text block.
1186: * @param outOff index in out where cipher-text starts.
1187: */
1188: private void blockEncrypt(byte[] in, int off, byte[] out, int outOff) {
1189: int L = (in[off++] & 0xFF) << 24 | (in[off++] & 0xFF) << 16
1190: | (in[off++] & 0xFF) << 8 | (in[off++] & 0xFF), R = (in[off++] & 0xFF) << 24
1191: | (in[off++] & 0xFF) << 16
1192: | (in[off++] & 0xFF) << 8
1193: | (in[off] & 0xFF);
1194:
1195: L ^= f1(R, Km0, Kr0);
1196: R ^= f2(L, Km1, Kr1); // round 2
1197: L ^= f3(R, Km2, Kr2);
1198: R ^= f1(L, Km3, Kr3); // round 4
1199: L ^= f2(R, Km4, Kr4);
1200: R ^= f3(L, Km5, Kr5); // round 6
1201: L ^= f1(R, Km6, Kr6);
1202: R ^= f2(L, Km7, Kr7); // round 8
1203: L ^= f3(R, Km8, Kr8);
1204: R ^= f1(L, Km9, Kr9); // round 10
1205: L ^= f2(R, Km10, Kr10);
1206: R ^= f3(L, Km11, Kr11); // round 12
1207: if (rounds == MAX_NOF_ROUNDS) {
1208: L ^= f1(R, Km12, Kr12);
1209: R ^= f2(L, Km13, Kr13); // round 14
1210: L ^= f3(R, Km14, Kr14);
1211: R ^= f1(L, Km15, Kr15); // round 16
1212: }
1213: out[outOff++] = (byte) (R >>> 24);
1214: out[outOff++] = (byte) (R >>> 16);
1215: out[outOff++] = (byte) (R >>> 8);
1216: out[outOff++] = (byte) R;
1217: out[outOff++] = (byte) (L >>> 24);
1218: out[outOff++] = (byte) (L >>> 16);
1219: out[outOff++] = (byte) (L >>> 8);
1220: out[outOff] = (byte) L;
1221: }
1222:
1223: /**
1224: * Decrypts a 64-bit block by applying the formulae and sub-keys
1225: * in reverse order to that of the encryption.
1226: *
1227: * @param input contains the cipher-text 64-bit block.
1228: * @param offset start index within input where data is considered.
1229: * @param out will contain the plain-text block.
1230: * @param outOff index in out where plain-text starts.
1231: */
1232: private void blockDecrypt(byte[] in, int off, byte[] out, int outOff) {
1233: int L = (in[off] & 0xFF) << 24 | (in[off + 1] & 0xFF) << 16
1234: | (in[off + 2] & 0xFF) << 8 | (in[off + 3] & 0xFF), R = (in[off + 4] & 0xFF) << 24
1235: | (in[off + 5] & 0xFF) << 16
1236: | (in[off + 6] & 0xFF) << 8 | (in[off + 7] & 0xFF);
1237:
1238: if (rounds == MAX_NOF_ROUNDS) {
1239: L ^= f1(R, Km15, Kr15);
1240: R ^= f3(L, Km14, Kr14);
1241: L ^= f2(R, Km13, Kr13);
1242: R ^= f1(L, Km12, Kr12);
1243: }
1244: L ^= f3(R, Km11, Kr11);
1245: R ^= f2(L, Km10, Kr10);
1246: L ^= f1(R, Km9, Kr9);
1247: R ^= f3(L, Km8, Kr8);
1248: L ^= f2(R, Km7, Kr7);
1249: R ^= f1(L, Km6, Kr6);
1250: L ^= f3(R, Km5, Kr5);
1251: R ^= f2(L, Km4, Kr4);
1252: L ^= f1(R, Km3, Kr3);
1253: R ^= f3(L, Km2, Kr2);
1254: L ^= f2(R, Km1, Kr1);
1255: R ^= f1(L, Km0, Kr0);
1256:
1257: out[outOff++] = (byte) (R >>> 24);
1258: out[outOff++] = (byte) (R >>> 16);
1259: out[outOff++] = (byte) (R >>> 8);
1260: out[outOff++] = (byte) R;
1261: out[outOff++] = (byte) (L >>> 24);
1262: out[outOff++] = (byte) (L >>> 16);
1263: out[outOff++] = (byte) (L >>> 8);
1264: out[outOff] = (byte) L;
1265: }
1266:
1267: private final int f1(int I, int m, int r) {
1268: I = m + I;
1269: I = I << r | I >>> (32 - r);
1270: return (((S1[(I >>> 24) & 0xFF]) ^ S2[(I >>> 16) & 0xFF]) - S3[(I >>> 8) & 0xFF])
1271: + S4[I & 0xFF];
1272: }
1273:
1274: private final int f2(int I, int m, int r) {
1275: I = m ^ I;
1276: I = I << r | I >>> (32 - r);
1277: return (((S1[(I >>> 24) & 0xFF]) - S2[(I >>> 16) & 0xFF]) + S3[(I >>> 8) & 0xFF])
1278: ^ S4[I & 0xFF];
1279: }
1280:
1281: private final int f3(int I, int m, int r) {
1282: I = m - I;
1283: I = I << r | I >>> (32 - r);
1284: return (((S1[(I >>> 24) & 0xFF]) + S2[(I >>> 16) & 0xFF]) ^ S3[(I >>> 8) & 0xFF])
1285: - S4[I & 0xFF];
1286: }
1287: }
|