summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorausiv4 <ausiv4@eb105b4a-77de-11de-a249-6bf219df57d5>2009-08-12 17:01:23 +0000
committerausiv4 <ausiv4@eb105b4a-77de-11de-a249-6bf219df57d5>2009-08-12 17:01:23 +0000
commit124ef39cb84dec12d21a36e98039e6a5042e7317 (patch)
tree91a0b28d2bf6b3b952d8b575a752d45193ca2d8b
parent900dc01238f0c0f6830d487d93f9176e711104fe (diff)
When upgrading the user from a non-srp account to an SRP account, the client must send the server the password. I wasn't happy about doing this
in plaintext, so I've incorporated slowAES on both the client and the server to encrypt the password before it is sent, using the key generated in the first SRP transaction.
-rw-r--r--django/srpproject/srp/aes.py655
-rw-r--r--django/srpproject/srp/views.py36
-rw-r--r--django/srpproject/templates/aes.html69
-rw-r--r--django/srpproject/urls.py2
-rw-r--r--javascript/aes.js771
-rw-r--r--javascript/cryptoHelpers.js185
-rw-r--r--javascript/jsPacker/build-pack-hash.sh2
-rw-r--r--javascript/jsPacker/hash.min.js2
-rw-r--r--javascript/jsPacker/srp.min.js2
-rw-r--r--javascript/srp.js25
10 files changed, 1742 insertions, 7 deletions
diff --git a/django/srpproject/srp/aes.py b/django/srpproject/srp/aes.py
new file mode 100644
index 0000000..4c27d41
--- /dev/null
+++ b/django/srpproject/srp/aes.py
@@ -0,0 +1,655 @@
+#!/usr/bin/python
+#
+# aes.py: implements AES - Advanced Encryption Standard
+# from the SlowAES project, http://code.google.com/p/slowaes/
+#
+# Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ),
+# Alex Martelli ( http://www.aleax.it )
+#
+# Ported from C code written by Laurent Haan ( http://www.progressive-coding.com )
+#
+# Licensed under the Apache License, Version 2.0
+# http://www.apache.org/licenses/
+#
+import os
+import sys
+import math
+
+def append_PKCS7_padding(s):
+ """return s padded to a multiple of 16-bytes by PKCS7 padding"""
+ numpads = 16 - (len(s)%16)
+ return s + numpads*chr(numpads)
+
+def strip_PKCS7_padding(s):
+ """return s stripped of PKCS7 padding"""
+ if len(s)%16 or not s:
+ raise ValueError("String of len %d can't be PCKS7-padded" % len(s))
+ numpads = ord(s[-1])
+ if numpads > 16:
+ raise ValueError("String ending with %r can't be PCKS7-padded" % s[-1])
+ return s[:-numpads]
+
+class AES(object):
+ # valid key sizes
+ keySize = dict(SIZE_128=16, SIZE_192=24, SIZE_256=32)
+
+ # Rijndael S-box
+ sbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67,
+ 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59,
+ 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7,
+ 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1,
+ 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05,
+ 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83,
+ 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29,
+ 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa,
+ 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
+ 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc,
+ 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
+ 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
+ 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee,
+ 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49,
+ 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4,
+ 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6,
+ 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70,
+ 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
+ 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e,
+ 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1,
+ 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0,
+ 0x54, 0xbb, 0x16]
+
+ # Rijndael Inverted S-box
+ rsbox = [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,
+ 0x9e, 0x81, 0xf3, 0xd7, 0xfb , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f,
+ 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb , 0x54,
+ 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
+ 0x42, 0xfa, 0xc3, 0x4e , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24,
+ 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 , 0x72, 0xf8,
+ 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,
+ 0x65, 0xb6, 0x92 , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 , 0x90, 0xd8, 0xab,
+ 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3,
+ 0x45, 0x06 , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1,
+ 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b , 0x3a, 0x91, 0x11, 0x41,
+ 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
+ 0x73 , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9,
+ 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e , 0x47, 0xf1, 0x1a, 0x71, 0x1d,
+ 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b ,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,
+ 0xfe, 0x78, 0xcd, 0x5a, 0xf4 , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07,
+ 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f , 0x60,
+ 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f,
+ 0x93, 0xc9, 0x9c, 0xef , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5,
+ 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 , 0x17, 0x2b,
+ 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55,
+ 0x21, 0x0c, 0x7d]
+
+ def getSBoxValue(self,num):
+ """Retrieves a given S-Box Value"""
+ return self.sbox[num]
+
+ def getSBoxInvert(self,num):
+ """Retrieves a given Inverted S-Box Value"""
+ return self.rsbox[num]
+
+ def rotate(self, word):
+ """ Rijndael's key schedule rotate operation.
+
+ Rotate a word eight bits to the left: eg, rotate(1d2c3a4f) == 2c3a4f1d
+ Word is an char list of size 4 (32 bits overall).
+ """
+ return word[1:] + word[:1]
+
+ # Rijndael Rcon
+ Rcon = [0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
+ 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97,
+ 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72,
+ 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66,
+ 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
+ 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
+ 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
+ 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61,
+ 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
+ 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+ 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
+ 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
+ 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
+ 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
+ 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
+ 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4,
+ 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
+ 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+ 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
+ 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2,
+ 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74,
+ 0xe8, 0xcb ]
+
+ def getRconValue(self, num):
+ """Retrieves a given Rcon Value"""
+ return self.Rcon[num]
+
+ def core(self, word, iteration):
+ """Key schedule core."""
+ # rotate the 32-bit word 8 bits to the left
+ word = self.rotate(word)
+ # apply S-Box substitution on all 4 parts of the 32-bit word
+ for i in range(4):
+ word[i] = self.getSBoxValue(word[i])
+ # XOR the output of the rcon operation with i to the first part
+ # (leftmost) only
+ word[0] = word[0] ^ self.getRconValue(iteration)
+ return word
+
+ def expandKey(self, key, size, expandedKeySize):
+ """Rijndael's key expansion.
+
+ Expands an 128,192,256 key into an 176,208,240 bytes key
+
+ expandedKey is a char list of large enough size,
+ key is the non-expanded key.
+ """
+ # current expanded keySize, in bytes
+ currentSize = 0
+ rconIteration = 1
+ expandedKey = [0] * expandedKeySize
+
+ # set the 16, 24, 32 bytes of the expanded key to the input key
+ for j in range(size):
+ expandedKey[j] = key[j]
+ currentSize += size
+
+ while currentSize < expandedKeySize:
+ # assign the previous 4 bytes to the temporary value t
+ t = expandedKey[currentSize-4:currentSize]
+
+ # every 16,24,32 bytes we apply the core schedule to t
+ # and increment rconIteration afterwards
+ if currentSize % size == 0:
+ t = self.core(t, rconIteration)
+ rconIteration += 1
+ # For 256-bit keys, we add an extra sbox to the calculation
+ if size == self.keySize["SIZE_256"] and ((currentSize % size) == 16):
+ for l in range(4): t[l] = self.getSBoxValue(t[l])
+
+ # We XOR t with the four-byte block 16,24,32 bytes before the new
+ # expanded key. This becomes the next four bytes in the expanded
+ # key.
+ for m in range(4):
+ expandedKey[currentSize] = expandedKey[currentSize - size] ^ \
+ t[m]
+ currentSize += 1
+
+ return expandedKey
+
+ def addRoundKey(self, state, roundKey):
+ """Adds (XORs) the round key to the state."""
+ for i in range(16):
+ state[i] ^= roundKey[i]
+ return state
+
+ def createRoundKey(self, expandedKey, roundKeyPointer):
+ """Create a round key.
+ Creates a round key from the given expanded key and the
+ position within the expanded key.
+ """
+ roundKey = [0] * 16
+ for i in range(4):
+ for j in range(4):
+ roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j]
+ return roundKey
+
+ def galois_multiplication(self, a, b):
+ """Galois multiplication of 8 bit characters a and b."""
+ p = 0
+ for counter in range(8):
+ if b & 1: p ^= a
+ hi_bit_set = a & 0x80
+ a <<= 1
+ # keep a 8 bit
+ a &= 0xFF
+ if hi_bit_set:
+ a ^= 0x1b
+ b >>= 1
+ return p
+
+ #
+ # substitute all the values from the state with the value in the SBox
+ # using the state value as index for the SBox
+ #
+ def subBytes(self, state, isInv):
+ if isInv: getter = self.getSBoxInvert
+ else: getter = self.getSBoxValue
+ for i in range(16): state[i] = getter(state[i])
+ return state
+
+ # iterate over the 4 rows and call shiftRow() with that row
+ def shiftRows(self, state, isInv):
+ for i in range(4):
+ state = self.shiftRow(state, i*4, i, isInv)
+ return state
+
+ # each iteration shifts the row to the left by 1
+ def shiftRow(self, state, statePointer, nbr, isInv):
+ for i in range(nbr):
+ if isInv:
+ state[statePointer:statePointer+4] = \
+ state[statePointer+3:statePointer+4] + \
+ state[statePointer:statePointer+3]
+ else:
+ state[statePointer:statePointer+4] = \
+ state[statePointer+1:statePointer+4] + \
+ state[statePointer:statePointer+1]
+ return state
+
+ # galois multiplication of the 4x4 matrix
+ def mixColumns(self, state, isInv):
+ # iterate over the 4 columns
+ for i in range(4):
+ # construct one column by slicing over the 4 rows
+ column = state[i:i+16:4]
+ # apply the mixColumn on one column
+ column = self.mixColumn(column, isInv)
+ # put the values back into the state
+ state[i:i+16:4] = column
+
+ return state
+
+ # galois multiplication of 1 column of the 4x4 matrix
+ def mixColumn(self, column, isInv):
+ if isInv: mult = [14, 9, 13, 11]
+ else: mult = [2, 1, 1, 3]
+ cpy = list(column)
+ g = self.galois_multiplication
+
+ column[0] = g(cpy[0], mult[0]) ^ g(cpy[3], mult[1]) ^ \
+ g(cpy[2], mult[2]) ^ g(cpy[1], mult[3])
+ column[1] = g(cpy[1], mult[0]) ^ g(cpy[0], mult[1]) ^ \
+ g(cpy[3], mult[2]) ^ g(cpy[2], mult[3])
+ column[2] = g(cpy[2], mult[0]) ^ g(cpy[1], mult[1]) ^ \
+ g(cpy[0], mult[2]) ^ g(cpy[3], mult[3])
+ column[3] = g(cpy[3], mult[0]) ^ g(cpy[2], mult[1]) ^ \
+ g(cpy[1], mult[2]) ^ g(cpy[0], mult[3])
+ return column
+
+ # applies the 4 operations of the forward round in sequence
+ def aes_round(self, state, roundKey):
+ state = self.subBytes(state, False)
+ state = self.shiftRows(state, False)
+ state = self.mixColumns(state, False)
+ state = self.addRoundKey(state, roundKey)
+ return state
+
+ # applies the 4 operations of the inverse round in sequence
+ def aes_invRound(self, state, roundKey):
+ state = self.shiftRows(state, True)
+ state = self.subBytes(state, True)
+ state = self.addRoundKey(state, roundKey)
+ state = self.mixColumns(state, True)
+ return state
+
+ # Perform the initial operations, the standard round, and the final
+ # operations of the forward aes, creating a round key for each round
+ def aes_main(self, state, expandedKey, nbrRounds):
+ state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
+ i = 1
+ while i < nbrRounds:
+ state = self.aes_round(state,
+ self.createRoundKey(expandedKey, 16*i))
+ i += 1
+ state = self.subBytes(state, False)
+ state = self.shiftRows(state, False)
+ state = self.addRoundKey(state,
+ self.createRoundKey(expandedKey, 16*nbrRounds))
+ return state
+
+ # Perform the initial operations, the standard round, and the final
+ # operations of the inverse aes, creating a round key for each round
+ def aes_invMain(self, state, expandedKey, nbrRounds):
+ state = self.addRoundKey(state,
+ self.createRoundKey(expandedKey, 16*nbrRounds))
+ i = nbrRounds - 1
+ while i > 0:
+ state = self.aes_invRound(state,
+ self.createRoundKey(expandedKey, 16*i))
+ i -= 1
+ state = self.shiftRows(state, True)
+ state = self.subBytes(state, True)
+ state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
+ return state
+
+ # encrypts a 128 bit input block against the given key of size specified
+ def encrypt(self, iput, key, size):
+ output = [0] * 16
+ # the number of rounds
+ nbrRounds = 0
+ # the 128 bit block to encode
+ block = [0] * 16
+ # set the number of rounds
+ if size == self.keySize["SIZE_128"]: nbrRounds = 10
+ elif size == self.keySize["SIZE_192"]: nbrRounds = 12
+ elif size == self.keySize["SIZE_256"]: nbrRounds = 14
+ else: return None
+
+ # the expanded keySize
+ expandedKeySize = 16*(nbrRounds+1)
+
+ # Set the block values, for the block:
+ # a0,0 a0,1 a0,2 a0,3
+ # a1,0 a1,1 a1,2 a1,3
+ # a2,0 a2,1 a2,2 a2,3
+ # a3,0 a3,1 a3,2 a3,3
+ # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+ #
+ # iterate over the columns
+ for i in range(4):
+ # iterate over the rows
+ for j in range(4):
+ block[(i+(j*4))] = iput[(i*4)+j]
+
+ # expand the key into an 176, 208, 240 bytes key
+ # the expanded key
+ expandedKey = self.expandKey(key, size, expandedKeySize)
+
+ # encrypt the block using the expandedKey
+ block = self.aes_main(block, expandedKey, nbrRounds)
+
+ # unmap the block again into the output
+ for k in range(4):
+ # iterate over the rows
+ for l in range(4):
+ output[(k*4)+l] = block[(k+(l*4))]
+ return output
+
+ # decrypts a 128 bit input block against the given key of size specified
+ def decrypt(self, iput, key, size):
+ output = [0] * 16
+ # the number of rounds
+ nbrRounds = 0
+ # the 128 bit block to decode
+ block = [0] * 16
+ # set the number of rounds
+ if size == self.keySize["SIZE_128"]: nbrRounds = 10
+ elif size == self.keySize["SIZE_192"]: nbrRounds = 12
+ elif size == self.keySize["SIZE_256"]: nbrRounds = 14
+ else: return None
+
+ # the expanded keySize
+ expandedKeySize = 16*(nbrRounds+1)
+
+ # Set the block values, for the block:
+ # a0,0 a0,1 a0,2 a0,3
+ # a1,0 a1,1 a1,2 a1,3
+ # a2,0 a2,1 a2,2 a2,3
+ # a3,0 a3,1 a3,2 a3,3
+ # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+
+ # iterate over the columns
+ for i in range(4):
+ # iterate over the rows
+ for j in range(4):
+ block[(i+(j*4))] = iput[(i*4)+j]
+ # expand the key into an 176, 208, 240 bytes key
+ expandedKey = self.expandKey(key, size, expandedKeySize)
+ # decrypt the block using the expandedKey
+ block = self.aes_invMain(block, expandedKey, nbrRounds)
+ # unmap the block again into the output
+ for k in range(4):
+ # iterate over the rows
+ for l in range(4):
+ output[(k*4)+l] = block[(k+(l*4))]
+ return output
+
+
+class AESModeOfOperation(object):
+
+ aes = AES()
+
+ # structure of supported modes of operation
+ modeOfOperation = dict(OFB=0, CFB=1, CBC=2)
+
+ # converts a 16 character string into a number array
+ def convertString(self, string, start, end, mode):
+ if end - start > 16: end = start + 16
+ if mode == self.modeOfOperation["CBC"]: ar = [0] * 16
+ else: ar = []
+
+ i = start
+ j = 0
+ while len(ar) < end - start:
+ ar.append(0)
+ while i < end:
+ ar[j] = ord(string[i])
+ j += 1
+ i += 1
+ return ar
+
+ # Mode of Operation Encryption
+ # stringIn - Input String
+ # mode - mode of type modeOfOperation
+ # hexKey - a hex key of the bit length size
+ # size - the bit length of the key
+ # hexIV - the 128 bit hex Initilization Vector
+ def encrypt(self, stringIn, mode, key, size, IV):
+ if len(key) % size:
+ return None
+ if len(IV) % 16:
+ return None
+ # the AES input/output
+ plaintext = []
+ iput = [0] * 16
+ output = []
+ ciphertext = [0] * 16
+ # the output cipher string
+ cipherOut = []
+ # char firstRound
+ firstRound = True
+ if stringIn != None:
+ for j in range(int(math.ceil(float(len(stringIn))/16))):
+ start = j*16
+ end = j*16+16
+ if end > len(stringIn):
+ end = len(stringIn)
+ plaintext = self.convertString(stringIn, start, end, mode)
+ # print 'PT@%s:%s' % (j, plaintext)
+ if mode == self.modeOfOperation["CFB"]:
+ if firstRound:
+ output = self.aes.encrypt(IV, key, size)
+ firstRound = False
+ else:
+ output = self.aes.encrypt(iput, key, size)
+ for i in range(16):
+ if len(plaintext)-1 < i:
+ ciphertext[i] = 0 ^ output[i]
+ elif len(output)-1 < i:
+ ciphertext[i] = plaintext[i] ^ 0
+ elif len(plaintext)-1 < i and len(output) < i:
+ ciphertext[i] = 0 ^ 0
+ else:
+ ciphertext[i] = plaintext[i] ^ output[i]
+ for k in range(end-start):
+ cipherOut.append(ciphertext[k])
+ iput = ciphertext
+ elif mode == self.modeOfOperation["OFB"]:
+ if firstRound:
+ output = self.aes.encrypt(IV, key, size)
+ firstRound = False
+ else:
+ output = self.aes.encrypt(iput, key, size)
+ for i in range(16):
+ if len(plaintext)-1 < i:
+ ciphertext[i] = 0 ^ output[i]
+ elif len(output)-1 < i:
+ ciphertext[i] = plaintext[i] ^ 0
+ elif len(plaintext)-1 < i and len(output) < i:
+ ciphertext[i] = 0 ^ 0
+ else:
+ ciphertext[i] = plaintext[i] ^ output[i]
+ for k in range(end-start):
+ cipherOut.append(ciphertext[k])
+ iput = output
+ elif mode == self.modeOfOperation["CBC"]:
+ for i in range(16):
+ if firstRound:
+ iput[i] = plaintext[i] ^ IV[i]
+ else:
+ iput[i] = plaintext[i] ^ ciphertext[i]
+ # print 'IP@%s:%s' % (j, iput)
+ firstRound = False
+ ciphertext = self.aes.encrypt(iput, key, size)
+ # always 16 bytes because of the padding for CBC
+ for k in range(16):
+ cipherOut.append(ciphertext[k])
+ return mode, len(stringIn), cipherOut
+
+ # Mode of Operation Decryption
+ # cipherIn - Encrypted String
+ # originalsize - The unencrypted string length - required for CBC
+ # mode - mode of type modeOfOperation
+ # key - a number array of the bit length size
+ # size - the bit length of the key
+ # IV - the 128 bit number array Initilization Vector
+ def decrypt(self, cipherIn, originalsize, mode, key, size, IV):
+ # cipherIn = unescCtrlChars(cipherIn)
+ if len(key) % size:
+ return None
+ if len(IV) % 16:
+ return None
+ # the AES input/output
+ ciphertext = []
+ iput = []
+ output = []
+ plaintext = [0] * 16
+ # the output plain text string
+ stringOut = ''
+ # char firstRound
+ firstRound = True
+ if cipherIn != None:
+ for j in range(int(math.ceil(float(len(cipherIn))/16))):
+ start = j*16
+ end = j*16+16
+ if j*16+16 > len(cipherIn):
+ end = len(cipherIn)
+ ciphertext = cipherIn[start:end]
+ if mode == self.modeOfOperation["CFB"]:
+ if firstRound:
+ output = self.aes.encrypt(IV, key, size)
+ firstRound = False
+ else:
+ output = self.aes.encrypt(iput, key, size)
+ for i in range(16):
+ if len(output)-1 < i:
+ plaintext[i] = 0 ^ ciphertext[i]
+ elif len(ciphertext)-1 < i:
+ plaintext[i] = output[i] ^ 0
+ elif len(output)-1 < i and len(ciphertext) < i:
+ plaintext[i] = 0 ^ 0
+ else:
+ plaintext[i] = output[i] ^ ciphertext[i]
+ for k in range(end-start):
+ stringOut += chr(plaintext[k])
+ iput = ciphertext
+ elif mode == self.modeOfOperation["OFB"]:
+ if firstRound:
+ output = self.aes.encrypt(IV, key, size)
+ firstRound = False
+ else:
+ output = self.aes.encrypt(iput, key, size)
+ for i in range(16):
+ if len(output)-1 < i:
+ plaintext[i] = 0 ^ ciphertext[i]
+ elif len(ciphertext)-1 < i:
+ plaintext[i] = output[i] ^ 0
+ elif len(output)-1 < i and len(ciphertext) < i:
+ plaintext[i] = 0 ^ 0
+ else:
+ plaintext[i] = output[i] ^ ciphertext[i]
+ for k in range(end-start):
+ stringOut += chr(plaintext[k])
+ iput = output
+ elif mode == self.modeOfOperation["CBC"]:
+ output = self.aes.decrypt(ciphertext, key, size)
+ for i in range(16):
+ if firstRound:
+ plaintext[i] = IV[i] ^ output[i]
+ else:
+ plaintext[i] = iput[i] ^ output[i]
+ firstRound = False
+ if originalsize is not None and originalsize < end:
+ for k in range(originalsize-start):
+ stringOut += chr(plaintext[k])
+ else:
+ for k in range(end-start):
+ stringOut += chr(plaintext[k])
+ iput = ciphertext
+ return stringOut
+
+
+def encryptData(key, data, mode=AESModeOfOperation.modeOfOperation["CBC"]):
+ """encrypt `data` using `key`
+
+ `key` should be a string of bytes.
+
+ returned cipher is a string of bytes prepended with the initialization
+ vector.
+
+ """
+ key = map(ord, key)
+ data = append_PKCS7_padding(data)
+ keysize = len(key)
+ assert keysize in AES.keySize.values(), 'invalid key size: %s' % keysize
+ # create a new iv using random data
+ iv = [ord(i) for i in os.urandom(16)]
+ moo = AESModeOfOperation()
+ (mode, length, ciph) = moo.encrypt(data, mode, key, keysize, iv)
+ # With padding, the original length does not need to be known. It's a bad
+ # idea to store the original message length.
+ # prepend the iv.
+ return ''.join(map(chr, iv)) + ''.join(map(chr, ciph))
+
+def decryptData(key, data, mode=AESModeOfOperation.modeOfOperation["CBC"]):
+ """decrypt `data` using `key`
+
+ `key` should be a string of bytes.
+
+ `data` should have the initialization vector prepended as a string or
+ ordinal values.
+
+ """
+
+ key = map(ord, key)
+ keysize = len(key)
+ assert keysize in AES.keySize.values(), 'invalid key size: %s' % keysize
+ # iv is first 16 bytes
+ iv = map(ord, data[:16])
+ data = map(ord, data[16:])
+ moo = AESModeOfOperation()
+ decr = moo.decrypt(data, None, mode, key, keysize, iv)
+ decr = strip_PKCS7_padding(decr)
+ return decr
+
+def generateRandomKey(keysize):
+ """Generates a key from random data of length `keysize`.
+
+ The returned key is a string of bytes.
+
+ """
+ if keysize not in (16, 24, 32):
+ emsg = 'Invalid keysize, %s. Should be one of (16, 24, 32).'
+ raise ValueError, emsg % keysize
+ return os.urandom(keysize)
+
+if __name__ == "__main__":
+ moo = AESModeOfOperation()
+ cleartext = "This is a test!"
+ cypherkey = [143,194,34,208,145,203,230,143,177,246,97,206,145,92,255,84]
+ iv = [103,35,148,239,76,213,47,118,255,222,123,176,106,134,98,92]
+ mode, orig_len, ciph = moo.encrypt(cleartext, moo.modeOfOperation["CBC"],
+ cypherkey, moo.aes.keySize["SIZE_128"], iv)
+ print 'm=%s, ol=%s (%s), ciph=%s' % (mode, orig_len, len(cleartext), ciph)
+ decr = moo.decrypt(ciph, orig_len, mode, cypherkey,
+ moo.aes.keySize["SIZE_128"], iv)
+ print decr
+
diff --git a/django/srpproject/srp/views.py b/django/srpproject/srp/views.py
index 8529fa9..cbf1389 100644
--- a/django/srpproject/srp/views.py
+++ b/django/srpproject/srp/views.py
@@ -25,6 +25,10 @@ def generate_fake_salt(I):
salt_chars = "./" + string.ascii_letters + string.digits
salt = "".join([random.choice(salt_chars) for i in range(0,16)])
return salt, int(hashlib.sha256("%s:%s" % (salt, settings.SECRET_KEY)).hexdigest(), 16)
+
+def test_aes(request):
+ from django.shortcuts import render_to_response
+ return render_to_response('aes.html',{'static_files': "http://%s/srp-test/javascript" % request.get_host()})
def login_page(request):
from django.shortcuts import render_to_response
@@ -150,7 +154,8 @@ def upgrade_add_verifier(request):
from django.contrib.auth.models import User
import hashlib
salt = generate_salt()
- x = int(hashlib.sha256(salt + hashlib.sha256("%s:%s" % (request.session["srp_I"], request.POST["p"])).hexdigest()).hexdigest(), 16)
+ key = hashlib.sha256(request.session["srp_S"]).hexdigest()
+ x = int(hashlib.sha256(salt + hashlib.sha256("%s:%s" % (request.session["srp_I"], decrypt(request.POST["p"], key, int(request.POST["l"])))).hexdigest()).hexdigest(), 16)
user = User.objects.get(username=request.session["srp_I"])
srpuser = SRPUser()
srpuser.__dict__.update(user.__dict__)
@@ -159,3 +164,32 @@ def upgrade_add_verifier(request):
srpuser.password = ""
srpuser.save()
return HttpResponse("<ok/>", mimetype="text/xml")
+
+def decrypt(c, key, plen):
+ from srp import aes
+ import base64
+ moo = aes.AESModeOfOperation()
+ cypherkey = map(ord, key.decode("hex"))
+ try:
+ ciphertext = base64.b64decode(c.replace("_", "+"))
+ except TypeError:
+ return HttpResponse("<error>%s</error>" % request.POST["c"], mimetype="text/xml" )
+ iv = map(ord, ciphertext[:16])
+ ciphertext= map(ord, ciphertext[16:])
+ return moo.decrypt(ciphertext, 0, moo.modeOfOperation["CFB"], cypherkey, len(cypherkey), iv)[:plen]
+
+
+def doaes(request):
+ from srp import aes
+ import base64
+ moo = aes.AESModeOfOperation()
+ cypherkey = map(ord, "6754c921b8dcbd1f8b58748cd87ac60ce857314687a65df05c470a46f438842c".decode("hex"))
+ try:
+ ciphertext = base64.b64decode(request.POST["c"].replace("_", "+"))
+ except TypeError:
+ return HttpResponse("<error>%s</error>" % request.POST["c"], mimetype="text/xml" )
+ iv = map(ord, ciphertext[:16])
+ ciphertext= map(ord, ciphertext[16:])
+ # (self, cipherIn, originalsize, mode, key, size, IV):
+ plaintext = moo.decrypt(ciphertext, int(request.POST["l"]), moo.modeOfOperation["OFB"], cypherkey, len(cypherkey), iv)[:int(request.POST["l"])]
+ return HttpResponse("<P>%s</P>" % plaintext, mimetype="text/xml" )
diff --git a/django/srpproject/templates/aes.html b/django/srpproject/templates/aes.html
new file mode 100644
index 0000000..dbdd4ac
--- /dev/null
+++ b/django/srpproject/templates/aes.html
@@ -0,0 +1,69 @@
+<html>
+ <head>
+ <script src="{{ static_files }}/prng4.js"></script>
+ <script src="{{ static_files }}/rng.js"></script>
+ <script src="{{ static_files }}/jsPacker/hash.min.js"></script>
+ <script type="text/javascript">
+ var key = cryptoHelpers.toNumbers("6754c921b8dcbd1f8b58748cd87ac60ce857314687a65df05c470a46f438842c");
+ var rng = new SecureRandom();
+ innerxml = function(node)
+ {
+ return node.firstChild.nodeValue;
+ };
+ ajaxRequest = function(full_url, params, callback)
+ {
+ if( window.XMLHttpRequest)
+ xhr = new XMLHttpRequest();
+ else if (window.ActiveXObject){
+ try{
+ xhr = new ActiveXObject("Microsoft.XMLHTTP");
+ }catch (e){}
+ }
+ else
+ {
+ that.error_message("Ajax not supported.");
+ return;
+ }
+ if(xhr){
+ xhr.onreadystatechange = callback;
+ xhr.open("POST", full_url, true);
+ xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ xhr.setRequestHeader("Content-length", params.length);
+ xhr.setRequestHeader("Connection", "close");
+ xhr.send(params);
+ }
+ else
+ {
+ that.error_message("Ajax failed.");
+ }
+ };
+ function encryptDecrypt()
+ {
+ var byteMessage = cryptoHelpers.convertStringToByteArray(document.getElementById("plaintext").value);
+ var iv = new Array(16);
+ rng.nextBytes(iv);
+ var paddedByteMessage = slowAES.getPaddedBlock(byteMessage, 0, byteMessage.length, slowAES.modeOfOperation.OFB);
+ var ciphertext = slowAES.encrypt(paddedByteMessage, slowAES.modeOfOperation.OFB, key, key.length, iv).cipher;
+ var sendstring = cryptoHelpers.base64.encode(iv.concat(ciphertext));
+ while(sendstring.indexOf("+",0) > -1)
+ sendstring = sendstring.replace("+", "_");
+ ajaxRequest("http://home.ausiv.com:85/srp/aes/post/", "c="+sendstring+"&l="+byteMessage.length, displayText);
+
+ };
+ function displayText()
+ {
+ if(xhr.readyState == 4 && xhr.status == 200) {
+ if(xhr.responseXML.getElementsByTagName("P").length > 0)
+ document.getElementById("output").value = innerxml(xhr.responseXML.getElementsByTagName("P")[0]);
+ else if(xhr.responseXML.getElementsByTagName("error").length > 0)
+ alert(innerxml(xhr.responseXML.getElementsByTagName("error")[0]));
+ }
+ };
+ </script>
+ </head>
+ <body>
+ <input type="text" id="plaintext"/>
+ <input type="button" value="Send Encrypted Text" onclick="javascript:encryptDecrypt();"/>
+ <input type="text" id="output"/>
+ </body>
+</html>
diff --git a/django/srpproject/urls.py b/django/srpproject/urls.py
index 550676e..07f446f 100644
--- a/django/srpproject/urls.py
+++ b/django/srpproject/urls.py
@@ -23,4 +23,6 @@ urlpatterns = patterns('',
(r'^srp/register/$', views.register_page),
(r'^srp/upgrade/authenticate/$', views.upgrade_auth),
(r'^srp/upgrade/verifier/$', views.upgrade_add_verifier),
+ (r'^srp/aes/$', views.test_aes),
+ (r'^srp/aes/post/$', views.doaes),
)
diff --git a/javascript/aes.js b/javascript/aes.js
new file mode 100644
index 0000000..5682618
--- /dev/null
+++ b/javascript/aes.js
@@ -0,0 +1,771 @@
+/*
+ * aes.js: implements AES - Advanced Encryption Standard
+ * from the SlowAES project, http://code.google.com/p/slowaes/
+ *
+ * Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ),
+ * Mark Percival ( http://mpercival.com ),
+ *
+ * Ported from C code written by Laurent Haan ( http://www.progressive-coding.com )
+ *
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/
+ */
+
+var slowAES = {
+ /*
+ * START AES SECTION
+ */
+ aes:{
+ // structure of valid key sizes
+ keySize:{
+ SIZE_128:16,
+ SIZE_192:24,
+ SIZE_256:32
+ },
+
+ // Rijndael S-box
+ sbox:[
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ],
+
+ // Rijndael Inverted S-box
+ rsbox:
+ [ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+ , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+ , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+ , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+ , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+ , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+ , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+ , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+ , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+ , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+ , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+ , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+ , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+ , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+ , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+ , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ],
+
+ /* rotate the word eight bits to the left */
+ rotate:function(word)
+ {
+ var c = word[0];
+ for (var i = 0; i < 3; i++)
+ word[i] = word[i+1];
+ word[3] = c;
+
+ return word;
+ },
+
+ // Rijndael Rcon
+ Rcon:[
+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+ 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
+ 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
+ 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab,
+ 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
+ 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25,
+ 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01,
+ 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
+ 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa,
+ 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
+ 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
+ 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+ 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
+ 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
+ 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
+ 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f,
+ 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
+ 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33,
+ 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb ],
+
+ G2X: [
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
+ 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
+ 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
+ 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+ 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
+ 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
+ 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
+ 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
+ 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
+ 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
+ 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+ 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
+ 0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
+ 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
+ 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+ 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
+ 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
+ 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
+ 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+ 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
+ 0xe3, 0xe1, 0xe7, 0xe5
+ ],
+
+ G3X: [
+ 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
+ 0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
+ 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
+ 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+ 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
+ 0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
+ 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
+ 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+ 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
+ 0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
+ 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
+ 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+ 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
+ 0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
+ 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
+ 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+ 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
+ 0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
+ 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
+ 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+ 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
+ 0x1f, 0x1c, 0x19, 0x1a
+ ],
+
+ G9X: [
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53,
+ 0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf,
+ 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20,
+ 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49,
+ 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd,
+ 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
+ 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e,
+ 0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2,
+ 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7,
+ 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
+ 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f,
+ 0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8,
+ 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c,
+ 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
+ 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9,
+ 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35,
+ 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba,
+ 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
+ 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62,
+ 0x5d, 0x54, 0x4f, 0x46
+ ],
+
+ GBX: [
+ 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45,
+ 0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81,
+ 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66,
+ 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
+ 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e,
+ 0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7,
+ 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b,
+ 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
+ 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8,
+ 0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c,
+ 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea,
+ 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
+ 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02,
+ 0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd,
+ 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21,
+ 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
+ 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44,
+ 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80,
+ 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67,
+ 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
+ 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f,
+ 0xbe, 0xb5, 0xa8, 0xa3
+ ],
+
+ GDX: [
+ 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f,
+ 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3,
+ 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac,
+ 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
+ 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14,
+ 0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e,
+ 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa,
+ 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
+ 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9,
+ 0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25,
+ 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd,
+ 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
+ 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75,
+ 0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42,
+ 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6,
+ 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
+ 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8,
+ 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44,
+ 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b,
+ 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
+ 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3,
+ 0x80, 0x8d, 0x9a, 0x97
+ ],
+
+ GEX: [
+ 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62,
+ 0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca,
+ 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9,
+ 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
+ 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59,
+ 0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87,
+ 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f,
+ 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
+ 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14,
+ 0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc,
+ 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53,
+ 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
+ 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3,
+ 0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0,
+ 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68,
+ 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
+ 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e,
+ 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26,
+ 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25,
+ 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
+ 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5,
+ 0x9f, 0x91, 0x83, 0x8d
+ ],
+
+ // Key Schedule Core
+ core:function(word,iteration)
+ {
+ /* rotate the 32-bit word 8 bits to the left */
+ word = this.rotate(word);
+ /* apply S-Box substitution on all 4 parts of the 32-bit word */
+ for (var i = 0; i < 4; ++i)
+ word[i] = this.sbox[word[i]];
+ /* XOR the output of the rcon operation with i to the first part (leftmost) only */
+ word[0] = word[0]^this.Rcon[iteration];
+ return word;
+ },
+
+ /* Rijndael's key expansion
+ * expands an 128,192,256 key into an 176,208,240 bytes key
+ *
+ * expandedKey is a pointer to an char array of large enough size
+ * key is a pointer to a non-expanded key
+ */
+ expandKey:function(key,size)
+ {
+ var expandedKeySize = (16*(this.numberOfRounds(size)+1));
+
+ /* current expanded keySize, in bytes */
+ var currentSize = 0;
+ var rconIteration = 1;
+ var t = []; // temporary 4-byte variable
+
+ var expandedKey = [];
+ for(var i = 0;i < expandedKeySize;i++)
+ expandedKey[i] = 0;
+
+ /* set the 16,24,32 bytes of the expanded key to the input key */
+ for (var j = 0; j < size; j++)
+ expandedKey[j] = key[j];
+ currentSize += size;
+
+ while (currentSize < expandedKeySize)
+ {
+ /* assign the previous 4 bytes to the temporary value t */
+ for (var k = 0; k < 4; k++)
+ t[k] = expandedKey[(currentSize - 4) + k];
+
+ /* every 16,24,32 bytes we apply the core schedule to t
+ * and increment rconIteration afterwards
+ */
+ if(currentSize % size == 0)
+ t = this.core(t, rconIteration++);
+
+ /* For 256-bit keys, we add an extra sbox to the calculation */
+ if(size == this.keySize.SIZE_256 && ((currentSize % size) == 16))
+ for(var l = 0; l < 4; l++)
+ t[l] = this.sbox[t[l]];
+
+ /* We XOR t with the four-byte block 16,24,32 bytes before the new expanded key.
+ * This becomes the next four bytes in the expanded key.
+ */
+ for(var m = 0; m < 4; m++) {
+ expandedKey[currentSize] = expandedKey[currentSize - size] ^ t[m];
+ currentSize++;
+ }
+ }
+ return expandedKey;
+ },
+
+ // Adds (XORs) the round key to the state
+ addRoundKey:function(state,roundKey)
+ {
+ for (var i = 0; i < 16; i++)
+ state[i] ^= roundKey[i];
+ return state;
+ },
+
+ // Creates a round key from the given expanded key and the
+ // position within the expanded key.
+ createRoundKey:function(expandedKey,roundKeyPointer)
+ {
+ var roundKey = [];
+ for (var i = 0; i < 4; i++)
+ for (var j = 0; j < 4; j++)
+ roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j];
+ return roundKey;
+ },
+
+ /* substitute all the values from the state with the value in the SBox
+ * using the state value as index for the SBox
+ */
+ subBytes:function(state,isInv)
+ {
+ for (var i = 0; i < 16; i++)
+ state[i] = isInv?this.rsbox[state[i]]:this.sbox[state[i]];
+ return state;
+ },
+
+ /* iterate over the 4 rows and call shiftRow() with that row */
+ shiftRows:function(state,isInv)
+ {
+ for (var i = 0; i < 4; i++)
+ state = this.shiftRow(state,i*4, i,isInv);
+ return state;
+ },
+
+ /* each iteration shifts the row to the left by 1 */
+ shiftRow:function(state,statePointer,nbr,isInv)
+ {
+ for (var i = 0; i < nbr; i++)
+ {
+ if(isInv)
+ {
+ var tmp = state[statePointer + 3];
+ for (var j = 3; j > 0; j--)
+ state[statePointer + j] = state[statePointer + j-1];
+ state[statePointer] = tmp;
+ }
+ else
+ {
+ var tmp = state[statePointer];
+ for (var j = 0; j < 3; j++)
+ state[statePointer + j] = state[statePointer + j+1];
+ state[statePointer + 3] = tmp;
+ }
+ }
+ return state;
+ },
+
+ // galois multiplication of 8 bit characters a and b
+ galois_multiplication:function(a,b)
+ {
+ var p = 0;
+ for(var counter = 0; counter < 8; counter++)
+ {
+ if((b & 1) == 1)
+ p ^= a;
+ if(p > 0x100) p ^= 0x100;
+ var hi_bit_set = (a & 0x80); //keep p 8 bit
+ a <<= 1;
+ if(a > 0x100) a ^= 0x100; //keep a 8 bit
+ if(hi_bit_set == 0x80)
+ a ^= 0x1b;
+ if(a > 0x100) a ^= 0x100; //keep a 8 bit
+ b >>= 1;
+ if(b > 0x100) b ^= 0x100; //keep b 8 bit
+ }
+ return p;
+ },
+
+ // galois multipication of the 4x4 matrix
+ mixColumns:function(state,isInv)
+ {
+ var column = [];
+ /* iterate over the 4 columns */
+ for (var i = 0; i < 4; i++)
+ {
+ /* construct one column by iterating over the 4 rows */
+ for (var j = 0; j < 4; j++)
+ column[j] = state[(j*4)+i];
+ /* apply the mixColumn on one column */
+ column = this.mixColumn(column,isInv);
+ /* put the values back into the state */
+ for (var k = 0; k < 4; k++)
+ state[(k*4)+i] = column[k];
+ }
+ return state;
+ },
+
+ // galois multipication of 1 column of the 4x4 matrix
+ mixColumn:function(column,isInv)
+ {
+ var mult = [];
+ if(isInv)
+ mult = [14,9,13,11];
+ else
+ mult = [2,1,1,3];
+ var cpy = [];
+ for(var i = 0; i < 4; i++)
+ cpy[i] = column[i];
+
+ column[0] = this.galois_multiplication(cpy[0],mult[0]) ^
+ this.galois_multiplication(cpy[3],mult[1]) ^
+ this.galois_multiplication(cpy[2],mult[2]) ^
+ this.galois_multiplication(cpy[1],mult[3]);
+ column[1] = this.galois_multiplication(cpy[1],mult[0]) ^
+ this.galois_multiplication(cpy[0],mult[1]) ^
+ this.galois_multiplication(cpy[3],mult[2]) ^
+ this.galois_multiplication(cpy[2],mult[3]);
+ column[2] = this.galois_multiplication(cpy[2],mult[0]) ^
+ this.galois_multiplication(cpy[1],mult[1]) ^
+ this.galois_multiplication(cpy[0],mult[2]) ^
+ this.galois_multiplication(cpy[3],mult[3]);
+ column[3] = this.galois_multiplication(cpy[3],mult[0]) ^
+ this.galois_multiplication(cpy[2],mult[1]) ^
+ this.galois_multiplication(cpy[1],mult[2]) ^
+ this.galois_multiplication(cpy[0],mult[3]);
+ return column;
+ },
+
+ // applies the 4 operations of the forward round in sequence
+ round:function(state, roundKey)
+ {
+ state = this.subBytes(state,false);
+ state = this.shiftRows(state,false);
+ state = this.mixColumns(state,false);
+ state = this.addRoundKey(state, roundKey);
+ return state;
+ },
+
+ // applies the 4 operations of the inverse round in sequence
+ invRound:function(state,roundKey)
+ {
+ state = this.shiftRows(state,true);
+ state = this.subBytes(state,true);
+ state = this.addRoundKey(state, roundKey);
+ state = this.mixColumns(state,true);
+ return state;
+ },
+
+ /*
+ * Perform the initial operations, the standard round, and the final operations
+ * of the forward aes, creating a round key for each round
+ */
+ main:function(state,expandedKey,nbrRounds)
+ {
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
+ for (var i = 1; i < nbrRounds; i++)
+ state = this.round(state, this.createRoundKey(expandedKey,16*i));
+ state = this.subBytes(state,false);
+ state = this.shiftRows(state,false);
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
+ return state;
+ },
+
+ /*
+ * Perform the initial operations, the standard round, and the final operations
+ * of the inverse aes, creating a round key for each round
+ */
+ invMain:function(state, expandedKey, nbrRounds)
+ {
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,16*nbrRounds));
+ for (var i = nbrRounds-1; i > 0; i--)
+ state = this.invRound(state, this.createRoundKey(expandedKey,16*i));
+ state = this.shiftRows(state,true);
+ state = this.subBytes(state,true);
+ state = this.addRoundKey(state, this.createRoundKey(expandedKey,0));
+ return state;
+ },
+
+ numberOfRounds:function(size)
+ {
+ var nbrRounds;
+ switch (size) /* set the number of rounds */
+ {
+ case this.keySize.SIZE_128:
+ nbrRounds = 10;
+ break;
+ case this.keySize.SIZE_192:
+ nbrRounds = 12;
+ break;
+ case this.keySize.SIZE_256:
+ nbrRounds = 14;
+ break;
+ default:
+ return null;
+ break;
+ }
+ return nbrRounds;
+ },
+
+ // encrypts a 128 bit input block against the given key of size specified
+ encrypt:function(input,key,size)
+ {
+ var output = [];
+ var block = []; /* the 128 bit block to encode */
+ var nbrRounds = this.numberOfRounds(size);
+ /* Set the block values, for the block:
+ * a0,0 a0,1 a0,2 a0,3
+ * a1,0 a1,1 a1,2 a1,3
+ * a2,0 a2,1 a2,2 a2,3
+ * a3,0 a3,1 a3,2 a3,3
+ * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+ */
+ for (var i = 0; i < 4; i++) /* iterate over the columns */
+ for (var j = 0; j < 4; j++) /* iterate over the rows */
+ block[(i+(j*4))] = input[(i*4)+j];
+
+ /* expand the key into an 176, 208, 240 bytes key */
+ var expandedKey = this.expandKey(key, size); /* the expanded key */
+ /* encrypt the block using the expandedKey */
+ block = this.main(block, expandedKey, nbrRounds);
+ for (var k = 0; k < 4; k++) /* unmap the block again into the output */
+ for (var l = 0; l < 4; l++) /* iterate over the rows */
+ output[(k*4)+l] = block[(k+(l*4))];
+ return output;
+ },
+
+ // decrypts a 128 bit input block against the given key of size specified
+ decrypt:function(input, key, size)
+ {
+ var output = [];
+ var block = []; /* the 128 bit block to decode */
+ var nbrRounds = this.numberOfRounds(size);
+ /* Set the block values, for the block:
+ * a0,0 a0,1 a0,2 a0,3
+ * a1,0 a1,1 a1,2 a1,3
+ * a2,0 a2,1 a2,2 a2,3
+ * a3,0 a3,1 a3,2 a3,3
+ * the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
+ */
+ for (var i = 0; i < 4; i++) /* iterate over the columns */
+ for (var j = 0; j < 4; j++) /* iterate over the rows */
+ block[(i+(j*4))] = input[(i*4)+j];
+ /* expand the key into an 176, 208, 240 bytes key */
+ var expandedKey = this.expandKey(key, size);
+ /* decrypt the block using the expandedKey */
+ block = this.invMain(block, expandedKey, nbrRounds);
+ for (var k = 0; k < 4; k++)/* unmap the block again into the output */
+ for (var l = 0; l < 4; l++)/* iterate over the rows */
+ output[(k*4)+l] = block[(k+(l*4))];
+ return output;
+ }
+ },
+ /*
+ * END AES SECTION
+ */
+
+ /*
+ * START MODE OF OPERATION SECTION
+ */
+ //structure of supported modes of operation
+ modeOfOperation:{
+ OFB:0,
+ CFB:1,
+ CBC:2
+ },
+
+ // gets a properly padded block
+ getPaddedBlock: function(bytesIn,start,end,mode)
+ {
+ if(end - start > 16)
+ end = start + 16;
+
+ var array = bytesIn.slice(start, end);
+
+ if (mode == this.modeOfOperation.CBC)
+ {
+ var cpad = 16 - array.length;
+ while(array.length < 16)
+ {
+ array.push(cpad);
+ }
+ }
+
+ return array;
+ },
+
+ /*
+ * Mode of Operation Encryption
+ * bytesIn - Input String as array of bytes
+ * mode - mode of type modeOfOperation
+ * key - a number array of length 'size'
+ * size - the bit length of the key
+ * iv - the 128 bit number array Initialization Vector
+ */
+ encrypt: function (bytesIn, mode, key, size, iv)
+ {
+ if(key.length%size)
+ {
+ throw 'Key length does not match specified size.';
+ }
+ if(iv.length%16)
+ {
+ throw 'iv length must be 128 bits.';
+ }
+ // the AES input/output
+ var byteArray = [];
+ var input = [];
+ var output = [];
+ var ciphertext = [];
+ var cipherOut = [];
+ // char firstRound
+ var firstRound = true;
+ if (bytesIn !== null)
+ {
+ for (var j = 0;j < Math.ceil(bytesIn.length/16); j++)
+ {
+ var start = j*16;
+ var end = j*16+16;
+ if(j*16+16 > bytesIn.length)
+ end = bytesIn.length;
+ byteArray = this.getPaddedBlock(bytesIn,start,end,mode);
+ if (mode == this.modeOfOperation.CFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (var i = 0; i < 16; i++)
+ ciphertext[i] = byteArray[i] ^ output[i];
+ for(var k = 0;k < end-start;k++)
+ cipherOut.push(ciphertext[k]);
+ input = ciphertext;
+ }
+ else if (mode == this.modeOfOperation.OFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (var i = 0; i < 16; i++)
+ ciphertext[i] = byteArray[i] ^ output[i];
+ for(var k = 0;k < end-start;k++)
+ cipherOut.push(ciphertext[k]);
+ input = output;
+ }
+ else if (mode == this.modeOfOperation.CBC)
+ {
+ for (var i = 0; i < 16; i++)
+ input[i] = byteArray[i] ^ ((firstRound) ? iv[i] : ciphertext[i]);
+ firstRound = false;
+ ciphertext = this.aes.encrypt(input, key, size);
+ // always 16 bytes because of the padding for CBC
+ for(var k = 0;k < 16;k++)
+ cipherOut.push(ciphertext[k]);
+ }
+ }
+ }
+ return {mode:mode,originalsize:bytesIn.length,cipher:cipherOut};
+ },
+
+ /*
+ * Mode of Operation Decryption
+ * cipherIn - Encrypted String as array of bytes
+ * originalsize - The unencrypted string length - required for CBC
+ * mode - mode of type modeOfOperation
+ * key - a number array of length 'size'
+ * size - the bit length of the key
+ * iv - the 128 bit number array Initialization Vector
+ */
+ decrypt:function(cipherIn,originalsize,mode,key,size,iv)
+ {
+ if(key.length%size)
+ {
+ throw 'Key length does not match specified size.';
+ return null;
+ }
+ if(iv.length%16)
+ {
+ throw 'iv length must be 128 bits.';
+ }
+ // the AES input/output
+ var ciphertext = [];
+ var input = [];
+ var output = [];
+ var byteArray = [];
+ var bytesOut = [];
+ // char firstRound
+ var firstRound = true;
+ if (cipherIn !== null)
+ {
+ for (var j = 0;j < Math.ceil(cipherIn.length/16); j++)
+ {
+ var start = j*16;
+ var end = j*16+16;
+ if(j*16+16 > cipherIn.length)
+ end = cipherIn.length;
+ ciphertext = this.getPaddedBlock(cipherIn,start,end,mode);
+ if (mode == this.modeOfOperation.CFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = output[i] ^ ciphertext[i];
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = ciphertext;
+ }
+ else if (mode == this.modeOfOperation.OFB)
+ {
+ if (firstRound)
+ {
+ output = this.aes.encrypt(iv, key, size);
+ firstRound = false;
+ }
+ else
+ output = this.aes.encrypt(input, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = output[i] ^ ciphertext[i];
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = output;
+ }
+ else if(mode == this.modeOfOperation.CBC)
+ {
+ output = this.aes.decrypt(ciphertext, key, size);
+ for (i = 0; i < 16; i++)
+ byteArray[i] = ((firstRound) ? iv[i] : input[i]) ^ output[i];
+ firstRound = false;
+ if (originalsize < end)
+ for(var k = 0;k < originalsize-start;k++)
+ bytesOut.push(byteArray[k]);
+ else
+ for(var k = 0;k < end-start;k++)
+ bytesOut.push(byteArray[k]);
+ input = ciphertext;
+ }
+ }
+ }
+ return bytesOut;
+ }
+ /*
+ * END MODE OF OPERATION SECTION
+ */
+};
+
diff --git a/javascript/cryptoHelpers.js b/javascript/cryptoHelpers.js
new file mode 100644
index 0000000..a77ee42
--- /dev/null
+++ b/javascript/cryptoHelpers.js
@@ -0,0 +1,185 @@
+/*
+ * cryptoHelpers.js: implements AES - Advanced Encryption Standard
+ * from the SlowAES project, http://code.google.com/p/slowaes/
+ *
+ * Copyright (c) 2008 Josh Davis ( http://www.josh-davis.org ),
+ * Mark Percival ( http://mpercival.com ),
+ * Johan Sundstrom ( http://ecmanaut.blogspot.com ),
+ * John Resig ( http://ejohn.org )
+ *
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/
+ */
+
+
+
+var cryptoHelpers = {
+
+ // encodes a unicode string to UTF8 (8 bit characters are critical to AES functioning properly)
+ encode_utf8:function(s)
+ {
+ try{return unescape(encodeURIComponent(s));}
+ catch(e){throw 'error during utf8 encoding: cryptoHelpers.encode_utf8.';}
+ },
+
+
+ // decodes a UTF8 string back to unicode
+ decode_utf8:function(s)
+ {
+ try{return decodeURIComponent(escape(s));}
+ catch(e){throw('error during utf8 decoding: cryptoHelpers.decode_utf8.');}
+ },
+
+ //convert a number array to a hex string
+ toHex:function()
+ {
+ var array = [];
+ if(arguments.length == 1 && arguments[0].constructor == Array)
+ array = arguments[0];
+ else
+ array = arguments;
+ var ret = '';
+ for(var i = 0;i < array.length;i++)
+ ret += (array[i] < 16 ? '0' : '') + array[i].toString(16);
+ return ret.toLowerCase();
+ },
+
+ //convert a hex string to a number array
+ toNumbers:function(s)
+ {
+ var ret = [];
+ s.replace(/(..)/g,function(s){
+ ret.push(parseInt(s,16));
+ });
+ return ret;
+ },
+
+ // get a random number in the range [min,max]
+ getRandom:function(min,max)
+ {
+ if(min === null)
+ min = 0;
+ if(max === null)
+ max = 1;
+ return Math.floor(Math.random()*(max+1)) + min;
+ },
+
+ generateSharedKey:function(len)
+ {
+ if(len === null)
+ len = 16;
+ var key = [];
+ for(var i = 0; i < len*2; i++)
+ key.push(this.getRandom(0,255));
+ return key;
+ },
+
+ generatePrivateKey:function(s,size)
+ {
+ var sha = jsHash.sha2.arr_sha256(s);
+ return sha.slice(0,size);
+ },
+
+ convertStringToByteArray: function(s)
+ {
+ var byteArray = [];
+ for(var i = 0;i < s.length;i++)
+ {
+ byteArray.push(s.charCodeAt(i));
+ }
+ return byteArray;
+ },
+
+ convertByteArrayToString: function(byteArray)
+ {
+ var s = '';
+ for(var i = 0;i < byteArray.length;i++)
+ {
+ s += String.fromCharCode(byteArray[i]);
+ }
+ return s;
+ },
+
+ base64: {
+ // Takes a Nx16x1 byte array and converts it to Base64
+
+ chars: [
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/',
+ '=' // for decoding purposes
+ ],
+
+ encode_line: function(flatArr){
+ var b64 = '';
+
+ for (var i = 0; i < flatArr.length; i += 3){
+ b64 += this.chars[flatArr[i] >> 2];
+ b64 += this.chars[((flatArr[i] & 3) << 4) | (flatArr[i + 1] >> 4)];
+ if (!(flatArr[i + 1] === null)){
+ b64 += this.chars[((flatArr[i + 1] & 15) << 2) | (flatArr[i + 2] >> 6)];
+ }else{
+ b64 += '=';
+ }
+ if (!(flatArr[i + 2] === null)){
+ b64 += this.chars[flatArr[i + 2] & 63];
+ }else{
+ b64 += '=';
+ }
+ }
+ return b64;
+ },
+
+ encode: function(flatArr)
+ {
+ var b64 = this.encode_line(flatArr);
+ // OpenSSL is super particular about line breaks
+ var broken_b64 = b64.slice(0, 64) + '\n';
+ for (var i = 1; i < (Math.ceil(b64.length / 64)); i++)
+ {
+ broken_b64 += b64.slice(i * 64, i * 64 + 64) + (Math.ceil(b64.length / 64) == i + 1 ? '': '\n');
+ }
+ return broken_b64;
+ },
+
+ decode: function(string)
+ {
+ string = string.replace(/[\r\n\t ]+/g, '') + '===='; // drop all whitespaces and pad with '=' (end of b64 marker)
+ var flatArr = [];
+ var c = [];
+ //var b = [];
+ for (var i = 0; true ; i = i + 4){
+ c[0] = this.chars.indexOf(string.charAt(i));
+ if(c[0] == 64){
+ return flatArr;
+ }
+ c[1] = this.chars.indexOf(string.charAt(i + 1));
+ c[2] = this.chars.indexOf(string.charAt(i + 2));
+ c[3] = this.chars.indexOf(string.charAt(i + 3));
+
+ if(
+ (c[0] < 0) || // char1 is wrong
+ (c[1] < 0) || (c[1] == 64) || // char2 is wrong
+ (c[2] < 0) || // char3 is neither an valid char nor '='
+ (c[3] < 0) // char4 is neither an valid char nor '='
+ ){
+ throw 'error during base64 decoding at pos '+i+': cryptoHelpers.base64.decode.';
+ }
+
+ flatArr.push((c[0] << 2) | (c[1] >> 4));
+ if(c[2] >= 0 && c[2] < 64){
+ flatArr.push(((c[1] & 15) << 4) | (c[2] >> 2));
+ if(c[3] >= 0 && c[2] < 64){
+ flatArr.push(((c[2] & 3) << 6) | c[3]);
+ }
+ }
+ }
+ }
+ }
+};
+
diff --git a/javascript/jsPacker/build-pack-hash.sh b/javascript/jsPacker/build-pack-hash.sh
index 45e841a..adeaefe 100644
--- a/javascript/jsPacker/build-pack-hash.sh
+++ b/javascript/jsPacker/build-pack-hash.sh
@@ -1,4 +1,4 @@
#!/bin/bash
-cat ../SHA1.js ../MD5.js > hash.js
+cat ../aes.js ../cryptoHelpers.js ../SHA1.js ../MD5.js > hash.js
perl jsPacker.pl -fsq -e62 -i hash.js -o hash.min.js
rm hash.js
diff --git a/javascript/jsPacker/hash.min.js b/javascript/jsPacker/hash.min.js
index a34be63..d8dbba6 100644
--- a/javascript/jsPacker/hash.min.js
+++ b/javascript/jsPacker/hash.min.js
@@ -1 +1 @@
-eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('l 41(K){l S(n,s){e 2x=(n<<s)|(n>>>(32-s));f 2x};l 3Z(1K){e 1g="";e i;e 2e;e 2d;J(i=0;i<=6;i+=2){2e=(1K>>>(i*4+4))&2c;2d=(1K>>>(i*4))&2c;1g+=2e.1P(16)+2d.1P(16)}f 1g};l 1f(1K){e 1g="";e i;e v;J(i=7;i>=0;i--){v=(1K>>>(i*4))&2c;1g+=v.1P(16)}f 1g};l 1L(u){u=u.2p(/\\r\\n/g,"\\n");e w="";J(e n=0;n<u.U;n++){e c=u.M(n);Z(c<V){w+=O.N(c)}1c Z((c>2o)&&(c<2n)){w+=O.N((c>>6)|2m);w+=O.N((c&1b)|V)}1c{w+=O.N((c>>12)|2l);w+=O.N(((c>>6)&1b)|V);w+=O.N((c&1b)|V)}}f w};e 1I;e i,j;e W=2w 1M(3Y);e 1H=2j;e 1G=2i;e 1F=2h;e 1E=2g;e 1D=3X;e A,B,C,D,E;e L;K=1L(K);e P=K.U;e T=2w 1M();J(i=0;i<P-3;i+=4){j=K.M(i)<<24|K.M(i+1)<<16|K.M(i+2)<<8|K.M(i+3);T.1J(j)}3W(P%4){1X 0:i=3V;1W;1X 1:i=K.M(P-1)<<24|3U;1W;1X 2:i=K.M(P-2)<<24|K.M(P-1)<<16|3T;1W;1X 3:i=K.M(P-3)<<24|K.M(P-2)<<16|K.M(P-1)<<8|2q;1W}T.1J(i);2r((T.U%16)!=14)T.1J(0);T.1J(P>>>29);T.1J((P<<3)&R);J(1I=0;1I<T.U;1I+=16){J(i=0;i<16;i++)W[i]=T[1I+i];J(i=16;i<=2v;i++)W[i]=S(W[i-3]^W[i-8]^W[i-14]^W[i-16],1);A=1H;B=1G;C=1F;D=1E;E=1D;J(i=0;i<=19;i++){L=(S(A,5)+((B&C)|(~B&D))+E+W[i]+3S)&R;E=D;D=C;C=S(B,30);B=A;A=L}J(i=20;i<=39;i++){L=(S(A,5)+(B^C^D)+E+W[i]+3R)&R;E=D;D=C;C=S(B,30);B=A;A=L}J(i=40;i<=3Q;i++){L=(S(A,5)+((B&C)|(B&D)|(C&D))+E+W[i]+3P)&R;E=D;D=C;C=S(B,30);B=A;A=L}J(i=3O;i<=2v;i++){L=(S(A,5)+(B^C^D)+E+W[i]+3N)&R;E=D;D=C;C=S(B,30);B=A;A=L}1H=(1H+A)&R;1G=(1G+B)&R;1F=(1F+C)&R;1E=(1E+D)&R;1D=(1D+E)&R}e L=1f(1H)+1f(1G)+1f(1F)+1f(1E)+1f(1D);f L.2f()}e 3M=l(u){l 1C(1z,2b){f(1z<<2b)|(1z>>>(32-2b))}l h(1V,1U){e 1T,1S,1e,1d,1a;1e=(1V&2a);1d=(1U&2a);1T=(1V&1R);1S=(1U&1R);1a=(1V&2u)+(1U&2u);Z(1T&1S){f(1a^2a^1e^1d)}Z(1T|1S){Z(1a&1R){f(1a^3L^1e^1d)}1c{f(1a^1R^1e^1d)}}1c{f(1a^1e^1d)}}l F(x,y,z){f(x&y)|((~x)&z)}l G(x,y,z){f(x&z)|(y&(~z))}l H(x,y,z){f(x^y^z)}l I(x,y,z){f(y^(x|(~z)))}l t(a,b,c,d,x,s,Y){a=h(a,h(h(F(b,c,d),x),Y));f h(1C(a,s),b)};l q(a,b,c,d,x,s,Y){a=h(a,h(h(G(b,c,d),x),Y));f h(1C(a,s),b)};l o(a,b,c,d,x,s,Y){a=h(a,h(h(H(b,c,d),x),Y));f h(1C(a,s),b)};l m(a,b,c,d,x,s,Y){a=h(a,h(h(I(b,c,d),x),Y));f h(1C(a,s),b)};l 2k(u){e 18;e 1A=u.U;e 28=1A+8;e 2s=(28-(28%2t))/2t;e 1Q=(2s+1)*16;e X=1M(1Q-1);e 1B=0;e Q=0;2r(Q<1A){18=(Q-(Q%4))/4;1B=(Q%4)*8;X[18]=(X[18]|(u.M(Q)<<1B));Q++}18=(Q-(Q%4))/4;1B=(Q%4)*8;X[18]=X[18]|(2q<<1B);X[1Q-2]=1A<<3;X[1Q-1]=1A>>>29;f X};l 1h(1z){e 1N="",1O="",27,1y;J(1y=0;1y<=3;1y++){27=(1z>>>(1y*8))&3K;1O="0"+27.1P(16);1N=1N+1O.3J(1O.U-2,2)}f 1N};l 1L(u){u=u.2p(/\\r\\n/g,"\\n");e w="";J(e n=0;n<u.U;n++){e c=u.M(n);Z(c<V){w+=O.N(c)}1c Z((c>2o)&&(c<2n)){w+=O.N((c>>6)|2m);w+=O.N((c&1b)|V)}1c{w+=O.N((c>>12)|2l);w+=O.N(((c>>6)&1b)|V);w+=O.N((c&1b)|V)}}f w};e x=1M();e k,26,25,1Z,1Y,a,b,c,d;e 1x=7,1w=12,1v=17,1u=22;e 1t=5,1s=9,1r=14,1q=20;e 1p=4,1o=11,1n=16,1m=23;e 1l=6,1k=10,1j=15,1i=21;u=1L(u);x=2k(u);a=2j;b=2i;c=2h;d=2g;J(k=0;k<x.U;k+=16){26=a;25=b;1Z=c;1Y=d;a=t(a,b,c,d,x[k+0],1x,3I);d=t(d,a,b,c,x[k+1],1w,3H);c=t(c,d,a,b,x[k+2],1v,3G);b=t(b,c,d,a,x[k+3],1u,3F);a=t(a,b,c,d,x[k+4],1x,3E);d=t(d,a,b,c,x[k+5],1w,3D);c=t(c,d,a,b,x[k+6],1v,3C);b=t(b,c,d,a,x[k+7],1u,3B);a=t(a,b,c,d,x[k+8],1x,3A);d=t(d,a,b,c,x[k+9],1w,3z);c=t(c,d,a,b,x[k+10],1v,3y);b=t(b,c,d,a,x[k+11],1u,3x);a=t(a,b,c,d,x[k+12],1x,3w);d=t(d,a,b,c,x[k+13],1w,3v);c=t(c,d,a,b,x[k+14],1v,3u);b=t(b,c,d,a,x[k+15],1u,3t);a=q(a,b,c,d,x[k+1],1t,3s);d=q(d,a,b,c,x[k+6],1s,3r);c=q(c,d,a,b,x[k+11],1r,3q);b=q(b,c,d,a,x[k+0],1q,3p);a=q(a,b,c,d,x[k+5],1t,3o);d=q(d,a,b,c,x[k+10],1s,3n);c=q(c,d,a,b,x[k+15],1r,3m);b=q(b,c,d,a,x[k+4],1q,3l);a=q(a,b,c,d,x[k+9],1t,3k);d=q(d,a,b,c,x[k+14],1s,3j);c=q(c,d,a,b,x[k+3],1r,3i);b=q(b,c,d,a,x[k+8],1q,3h);a=q(a,b,c,d,x[k+13],1t,3g);d=q(d,a,b,c,x[k+2],1s,3f);c=q(c,d,a,b,x[k+7],1r,3e);b=q(b,c,d,a,x[k+12],1q,3d);a=o(a,b,c,d,x[k+5],1p,3c);d=o(d,a,b,c,x[k+8],1o,3b);c=o(c,d,a,b,x[k+11],1n,3a);b=o(b,c,d,a,x[k+14],1m,38);a=o(a,b,c,d,x[k+1],1p,37);d=o(d,a,b,c,x[k+4],1o,36);c=o(c,d,a,b,x[k+7],1n,35);b=o(b,c,d,a,x[k+10],1m,34);a=o(a,b,c,d,x[k+13],1p,33);d=o(d,a,b,c,x[k+0],1o,31);c=o(c,d,a,b,x[k+3],1n,2Z);b=o(b,c,d,a,x[k+6],1m,2Y);a=o(a,b,c,d,x[k+9],1p,2X);d=o(d,a,b,c,x[k+12],1o,2W);c=o(c,d,a,b,x[k+15],1n,2V);b=o(b,c,d,a,x[k+2],1m,2U);a=m(a,b,c,d,x[k+0],1l,2T);d=m(d,a,b,c,x[k+7],1k,2S);c=m(c,d,a,b,x[k+14],1j,2R);b=m(b,c,d,a,x[k+5],1i,2Q);a=m(a,b,c,d,x[k+12],1l,2P);d=m(d,a,b,c,x[k+3],1k,2O);c=m(c,d,a,b,x[k+10],1j,2N);b=m(b,c,d,a,x[k+1],1i,2M);a=m(a,b,c,d,x[k+8],1l,2L);d=m(d,a,b,c,x[k+15],1k,2K);c=m(c,d,a,b,x[k+6],1j,2J);b=m(b,c,d,a,x[k+13],1i,2I);a=m(a,b,c,d,x[k+4],1l,2H);d=m(d,a,b,c,x[k+11],1k,2G);c=m(c,d,a,b,x[k+2],1j,2F);b=m(b,c,d,a,x[k+9],1i,2E);a=h(a,26);b=h(b,25);c=h(c,1Z);d=h(d,1Y)}e L=1h(a)+1h(b)+1h(c)+1h(d);f L.2f()}2D.2C.2B=l(s,2A,2z,2y,p){};',62,250,'||||||||||||||var|return||AddUnsigned||||function|II||HH||GG|||FF|string||utftext|||||||||||||for|msg|temp|charCodeAt|fromCharCode|String|msg_len|lByteCount|0x0ffffffff|rotate_left|word_array|length|128||lWordArray|ac|if|||||||||lWordCount||lResult|63|else|lY8|lX8|cvt_hex|str|WordToHex|S44|S43|S42|S41|S34|S33|S32|S31|S24|S23|S22|S21|S14|S13|S12|S11|lCount|lValue|lMessageLength|lBytePosition|RotateLeft|H4|H3|H2|H1|H0|blockstart|push|val|Utf8Encode|Array|WordToHexValue|WordToHexValue_temp|toString|lNumberOfWords|0x40000000|lY4|lX4|lY|lX|break|case|DD|CC||||||BB|AA|lByte|lNumberOfWords_temp1||0x80000000|iShiftBits|0x0f|vl|vh|toLowerCase|0x10325476|0x98BADCFE|0xEFCDAB89|0x67452301|ConvertToWordArray|224|192|2048|127|replace|0x80|while|lNumberOfWords_temp2|64|0x3FFFFFFF|79|new|t4|dsalt|algo|ephemeral|upgrade|prototype|SRP|0xEB86D391|0x2AD7D2BB|0xBD3AF235|0xF7537E82|0x4E0811A1|0xA3014314|0xFE2CE6E0|0x6FA87E4F|0x85845DD1|0xFFEFF47D|0x8F0CCC92|0x655B59C3|0xFC93A039|0xAB9423A7|0x432AFF97|0xF4292244|0xC4AC5665|0x1FA27CF8|0xE6DB99E5|0xD9D4D039|0x4881D05|0xD4EF3085||0xEAA127FA||0x289B7EC6|0xBEBFBC70|0xF6BB4B60|0x4BDECFA9|0xA4BEEA44|0xFDE5380C||0x6D9D6122|0x8771F681|0xFFFA3942|0x8D2A4C8A|0x676F02D9|0xFCEFA3F8|0xA9E3E905|0x455A14ED|0xF4D50D87|0xC33707D6|0x21E1CDE6|0xE7D3FBC8|0xD8A1E681|0x2441453|0xD62F105D|0xE9B6C7AA|0x265E5A51|0xC040B340|0xF61E2562|0x49B40821|0xA679438E|0xFD987193|0x6B901122|0x895CD7BE|0xFFFF5BB1|0x8B44F7AF|0x698098D8|0xFD469501|0xA8304613|0x4787C62A|0xF57C0FAF|0xC1BDCEEE|0x242070DB|0xE8C7B756|0xD76AA478|substr|255|0xC0000000|MD5|0xCA62C1D6|60|0x8F1BBCDC|59|0x6ED9EBA1|0x5A827999|0x08000|0x0800000|0x080000000|switch|0xC3D2E1F0|80|lsb_hex||SHA1'.split('|'),0,{}))
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('18 aI={2O:{7j:{8L:16,8K:24,86:32},7K:[1W,3z,4D,5g,6g,4B,5A,1U,4W,1Y,5e,3s,3O,3j,2E,56,6d,69,5Y,2C,2r,5C,3q,3P,5z,2d,4e,4s,3L,3I,27,44,5S,3f,5Q,3A,2H,4z,5l,2p,3C,5T,5o,5U,3l,2F,4A,4u,2f,5Z,4x,4l,3V,4T,5b,2l,4v,6u,1x,3Q,5n,5L,4N,5h,4w,1Q,4U,4Z,1J,3x,6k,4O,52,5M,6f,2n,5K,5X,2x,4Q,4F,4o,6x,5W,2e,6h,5x,3o,2w,1V,4c,25,26,3Z,3v,5p,4J,1T,3H,4h,5k,2z,2y,4q,5E,5m,2b,3m,3Y,3T,1S,68,5j,5y,2v,5O,3K,5P,6t,4i,2t,3F,3N,5c,2a,5V,3g,47,4m,3E,3r,3R,5i,2m,3w,57,6e,3e,6p,5d,54,4G,58,5B,3y,5N,4H,46,4V,6r,6c,4f,6m,6i,3G,4Y,4K,2g,5a,62,6j,3U,28,3X,3p,50,6s,51,2q,2A,4d,6o,1R,5v,2j,4E,4j,3M,3t,3k,1P,61,53,3d,2G,3u,4L,4a,4C,43,4P,2u,65,55,1Z,3S,6v,67,66,2c,2s,5r,2i,5H,5F,2o,4p,4R,6q,4X,3b,2h,6n,5J,49,6w,2B,2D,5D,5R,4g,5q,1X,6b,3h,48,4S,5G,5f,3i,3J,2k,5u,3D,5s,4k,45,3n,3B,4n,6a,4t,5t,5I,5w,4M,41,42,4I,4r,4y,2L,4b,6l,3c,3W],8S:[52,4w,2w,61,4W,2H,5T,6t,5w,2v,5y,6b,5N,3g,3j,4h,3z,5X,25,69,5u,2x,5V,5s,3C,3J,5k,3w,6e,4K,4k,1V,6l,5g,2k,3U,67,2q,4x,5d,6i,3Z,5v,5a,41,2r,4l,53,2u,3S,4t,2h,3B,3i,6s,4N,56,3o,4e,3p,3k,4p,4o,1Z,27,48,49,54,4g,42,4S,3W,2d,3I,51,2p,4G,4C,3F,3K,2G,6q,6n,3Y,3f,5W,5R,3N,2g,4u,6m,5D,3e,1P,5P,4Q,6c,2F,2E,6x,6a,2t,2A,3X,5l,2j,3v,5b,3G,2n,5E,50,4J,4U,3D,5O,6d,4z,2L,2b,5q,4s,2o,5J,1Y,3r,4R,4B,28,1R,5G,4I,4H,5e,46,4a,2m,6g,5p,45,3P,66,4M,5B,4T,4d,2i,4V,4j,5z,2D,4q,3Q,5m,3t,2s,6v,5h,4n,3x,3q,5U,4Z,3l,1X,5K,1U,5t,5A,5S,6o,6w,3H,3V,4c,1J,6h,3u,4X,5F,2c,47,4E,2e,2l,62,44,3O,55,4m,6k,4L,5H,5r,68,2y,4f,4v,5Z,4A,5x,6u,2a,5C,5L,1x,3R,5i,3y,5j,3m,3d,58,3b,26,5I,4y,5o,43,1S,5Q,5Y,3L,1T,4O,6j,5M,2z,4P,6r,4i,4b,3M,5n,3c,3T,1Q,4F,4r,2B,57,3s,2f,6p,65,4D,6f,3A,3h,5f,4Y,1W,3n,5c,3E,2C],8Y:1e(1K){18 c=1K[0];1c(18 i=0;i<3;i++)1K[i]=1K[i+1];1K[3]=c;1d 1K},8X:[1P,1Y,2b,2f,2u,2a,2e,2v,1x,1J,2H,2G,2F,2E,2z,2l,2x,2g,2t,1W,2c,2m,2D,2w,2d,2n,2C,2r,1T,1U,1R,25,27,2j,2A,2o,2B,2q,1S,1Z,26,2k,2y,2h,2p,1Q,1X,28,2i,2s,1V,1P,1Y,2b,2f,2u,2a,2e,2v,1x,1J,2H,2G,2F,2E,2z,2l,2x,2g,2t,1W,2c,2m,2D,2w,2d,2n,2C,2r,1T,1U,1R,25,27,2j,2A,2o,2B,2q,1S,1Z,26,2k,2y,2h,2p,1Q,1X,28,2i,2s,1V,1P,1Y,2b,2f,2u,2a,2e,2v,1x,1J,2H,2G,2F,2E,2z,2l,2x,2g,2t,1W,2c,2m,2D,2w,2d,2n,2C,2r,1T,1U,1R,25,27,2j,2A,2o,2B,2q,1S,1Z,26,2k,2y,2h,2p,1Q,1X,28,2i,2s,1V,1P,1Y,2b,2f,2u,2a,2e,2v,1x,1J,2H,2G,2F,2E,2z,2l,2x,2g,2t,1W,2c,2m,2D,2w,2d,2n,2C,2r,1T,1U,1R,25,27,2j,2A,2o,2B,2q,1S,1Z,26,2k,2y,2h,2p,1Q,1X,28,2i,2s,1V,1P,1Y,2b,2f,2u,2a,2e,2v,1x,1J,2H,2G,2F,2E,2z,2l,2x,2g,2t,1W,2c,2m,2D,2w,2d,2n,2C,2r,1T,1U,1R,25,27,2j,2A,2o,2B,2q,1S,1Z,26,2k,2y,2h,2p,1Q,1X,28,2i,2s,1V],aH:[6x,2b,2f,50,2u,3X,3E,6w,2a,6u,4Y,3W,3V,4Z,6v,3D,2e,4V,6s,3A,3B,6r,4U,3S,4W,3U,3C,2H,6t,28,3T,4X,2v,41,3w,6m,6n,26,3Z,53,3Y,52,6l,3u,3v,6k,51,2g,3y,6o,54,2h,42,2w,2G,3x,6q,27,2i,56,55,43,3z,6p,1x,69,4Q,4g,4f,4R,6a,3J,6c,3K,2k,4T,4S,2l,3L,6b,4O,4e,3I,67,68,3H,4d,4P,4b,4N,66,3F,3G,65,2t,4c,44,2q,6e,2c,3M,6d,2p,45,4J,47,2d,6f,2F,3N,46,4K,6j,3Q,2j,4M,2s,4a,3R,6i,3P,6g,4L,49,48,2r,6h,3O,1J,58,5H,1X,3r,5G,57,4u,5a,4w,2L,5I,5J,1Y,4v,5b,5M,25,4z,5d,2y,4A,3t,2D,3s,5K,2x,4y,4x,5c,5L,1Z,3o,5C,5i,4G,4F,5j,5D,3n,5F,3p,4H,2z,5k,4I,3q,5E,5g,4E,3m,2C,5B,3l,4D,5h,4B,5f,5A,3k,1W,2B,5e,4C,5u,4r,1S,5P,5Q,1R,2m,5v,4p,5t,5O,1P,1Q,5N,5s,4q,3c,5R,5w,2o,2n,5x,5S,3b,2E,3d,4s,5z,5y,4t,3e,5T,62,3i,4n,5r,2A,4o,3j,61,1V,5Y,5p,4m,4l,5q,5Z,1U,4h,5m,5V,3f,3g,5U,5l,4i,5n,4k,1T,5W,5X,3h,4j,5o],aG:[6x,5J,50,5b,3E,2L,3X,4w,3V,1J,3D,1X,4Y,57,6u,5G,4W,2y,2H,2D,3T,4z,28,25,3B,3s,3S,4y,6s,5L,4V,5c,3y,1W,2h,4C,2G,5A,2w,5f,55,5g,6p,2C,2i,4D,27,3l,3Y,4F,3u,3n,51,5i,6k,5C,6n,5F,53,2z,3w,3q,41,4I,44,4l,2c,1U,2p,5p,6d,5Y,2F,62,4K,5r,2d,3j,47,4o,3P,3g,49,4i,6h,5V,2r,5m,2s,5n,6i,5W,2j,4j,3Q,3h,4O,5y,67,5T,4d,4s,3H,3d,3G,3c,4c,2o,66,5S,4N,5x,6c,5Q,4T,5v,3L,1S,2l,4r,4f,4p,3J,1P,4Q,5s,69,5N,5u,4S,5P,6b,2m,2k,1R,3K,1Q,1x,4q,4g,5O,6a,5t,4R,2E,68,5z,4P,3e,3I,4t,4e,2n,4b,3b,3F,5w,2t,5R,65,4h,48,3f,3O,5l,4L,5U,6g,5X,6j,5o,4M,1T,3R,4k,4a,1V,3M,4m,45,5Z,6e,5q,2q,2A,4J,61,6f,4n,46,3i,3N,3o,3v,4G,2g,5D,6l,5j,52,5k,2v,5E,6m,4H,3Z,3p,26,4B,42,3k,3x,5e,54,2B,6o,5B,6q,5h,56,3m,3z,4E,43,5M,6t,5d,4X,3t,3C,4A,3U,4x,2e,1Z,3A,2x,4U,5K,6r,5a,2u,5I,6w,4v,2f,1Y,2b,3r,2a,4u,3W,5H,6v,58,4Z],aF:[6x,4w,6u,1J,6s,4y,2H,4z,6n,4I,6k,4F,2G,4C,6p,4D,6c,4r,69,4p,66,2o,67,4s,2F,4o,6d,4l,6h,4i,6i,4j,5M,3U,5K,2e,5H,3W,5I,2f,5B,43,2B,42,5D,2g,5E,3Z,2E,4e,5R,4b,5O,4g,5P,2k,5X,4a,5U,48,5Z,45,61,46,56,3m,54,3k,52,3o,2v,3p,4X,3t,4U,1Z,4Z,3r,2u,1Y,4M,1T,4L,3f,2q,1V,4J,3i,4P,3e,2t,3b,4R,1Q,4S,1R,2z,3w,5i,3u,5f,3y,5g,27,5b,3E,57,3D,5c,3B,2y,28,5r,2d,5p,2c,5m,3P,5n,3Q,5v,3L,5s,3J,5x,3G,5y,3H,3R,5o,3O,5l,3M,5q,3N,2A,3I,5z,3F,5w,1x,5t,3K,5u,3z,5h,3x,5e,3v,5j,26,5k,3C,5d,3A,2x,2a,58,2b,5a,3j,4K,1U,2p,3g,2r,3h,2s,1S,4T,1P,4Q,3c,4N,3d,4O,3q,53,3n,51,1W,2w,3l,55,2L,50,1X,4Y,3s,4V,25,4W,2l,5Q,4f,5N,4c,5S,4d,5T,47,62,44,5Y,49,5V,2j,5W,3X,5J,3V,5G,3S,5L,3T,2D,41,5F,3Y,5C,2h,5A,2i,2C,4t,68,2n,65,4q,6a,2m,6b,4k,6j,4h,6g,4m,6e,4n,6f,4A,6t,4x,6r,4u,6v,4v,6w,4E,6q,4B,6o,4G,6l,4H,6m],aE:[6x,5a,3W,1X,4U,5L,28,4A,3v,4F,53,5E,2i,3m,6o,5f,4b,3c,67,5z,3L,2m,4R,5N,2s,5X,3O,4i,6e,5p,47,3i,5g,6q,3k,2h,5D,51,4I,26,4x,3B,2D,4X,2L,2f,58,6u,1V,44,5r,6f,4j,3R,5U,2r,5Q,4S,4q,3J,5w,66,3d,4e,49,3f,6j,5n,3N,4o,2p,5Z,4P,5T,3G,2n,69,5t,2k,1S,6m,2z,3Y,3o,2w,2B,3z,4D,3D,4u,2u,5J,3U,25,6s,2x,1P,4g,5u,6c,4t,3H,5S,2t,61,4K,4l,3M,5m,6g,1T,2j,5d,2H,3s,2e,5G,4Z,4v,3E,4C,3x,5B,55,3p,41,5i,6l,5l,6h,3h,4a,62,4J,4m,2c,4s,3I,5R,4N,1Q,4f,5v,6b,3q,3Z,5j,6k,4B,3y,2C,56,5H,4Y,4w,2b,2y,6t,1Z,3S,6a,5s,2l,1R,4O,2E,3F,2o,2d,4n,2q,5Y,48,3g,6i,5o,3T,3t,6r,5c,2a,1J,50,5I,54,5A,27,4E,6n,5k,2g,3n,1Y,3X,57,6v,4y,3A,5M,4W,5C,52,4H,3w,5h,6p,1W,42,5x,65,3e,4d,5P,4T,4p,1x,4k,3Q,5V,4L,1U,45,2A,2F,43,3l,2G,5e,3u,4G,2v,5F,4V,5K,3C,4z,6w,5b,3V,3r,6d,5q,46,3j,4M,5W,3P,4h,3K,4r,4Q,5O,4c,3b,68,5y],aD:[6x,5I,4Z,57,3C,25,3S,4x,42,4C,27,3m,51,5j,6m,5F,4J,5r,6d,5Z,2j,4k,3O,3g,3G,3b,4e,4s,6a,5N,4T,5u,3c,3F,4t,4d,5O,69,5v,4S,2A,4K,5Y,6e,4j,4a,3f,3P,4B,2h,3l,3z,5i,52,5E,6n,5J,6w,58,4Y,3t,28,4y,2e,3k,3y,4D,43,5C,6l,5k,53,5b,2u,5H,6u,4A,3T,3s,3A,2o,4b,3e,3H,5t,4Q,5Q,6b,61,2F,5p,2q,3h,3R,4h,49,6f,62,2p,5q,3Q,1T,48,4i,4c,2n,3I,3d,4R,5s,6c,5P,50,5a,6v,5G,3U,4z,3B,1Z,3x,1W,2i,4E,6k,5D,2v,2z,3N,3j,44,4m,6i,5X,4L,5m,4N,5w,68,5T,4g,4p,3L,1R,3X,4v,2a,1X,4X,2y,6s,5K,6o,5A,55,5h,3u,3o,3Z,4I,2B,2G,5g,56,3n,3v,4H,41,4w,2f,3r,3D,5d,4W,5L,6r,5x,2t,2E,67,4q,4f,1S,3K,3i,2d,4l,45,5W,6j,5l,2r,5S,65,5z,4O,1Q,3J,4r,2k,4n,47,1U,3M,5n,4M,5U,6h,5e,2w,2C,6q,4F,2g,3p,3w,2L,2b,4u,3V,5M,2H,5c,4U,3E,1Y,3W,1J,6t,2D,4V,2x,54,5f,6p,5B,3Y,4G,26,3q,46,4o,2c,1V,2s,5o,6g,5V,66,5R,4P,5y,1x,1P,2l,2m],aC:[6x,6w,6v,6u,6t,2H,6s,6r,6q,6p,2G,6o,6n,6m,6l,6k,6j,6i,6h,6g,2F,6f,6e,6d,6c,6b,6a,69,68,67,66,65,62,61,5Z,5Y,5X,5W,5V,5U,2E,5T,5S,5R,5Q,5P,5O,5N,5M,2D,5L,5K,5J,5I,5H,5G,5F,5E,5D,5C,5B,2C,5A,2B,5z,5y,5x,5w,5v,5u,5t,5s,5r,2A,5q,5p,5o,5n,5m,5l,2z,5k,5j,5i,5h,5g,5f,5e,5d,2y,5c,2x,5b,5a,58,57,56,55,2w,54,53,2v,52,51,50,2u,4Z,4Y,4X,4W,4V,4U,4T,4S,4R,4Q,4P,4O,4N,2t,4M,2s,2r,4L,4K,4J,2q,2p,4I,4H,4G,4F,4E,4D,4C,4B,4A,4z,4y,4x,4w,4v,4u,1J,4t,4s,2o,2n,4r,2m,4q,4p,4o,4n,4m,4l,4k,4j,4i,4h,2l,2k,4g,4f,4e,4d,4c,4b,4a,2j,49,48,47,46,45,44,43,2i,2h,42,41,3Z,2g,3Y,3X,2f,3W,3V,3U,3T,3S,2e,3R,3Q,3P,3O,2d,3N,3M,2c,3L,3K,1x,3J,3I,3H,3G,3F,3E,2b,2a,3D,3C,28,3B,3A,3z,27,3y,3x,3w,26,3v,3u,3t,25,3s,1Z,2L,1Y,3r,1X,3q,3p,3o,3n,3m,3l,1W,3k,3j,3i,1V,1U,1T,3h,3g,3f,3e,3d,3c,3b,1S,1R,1Q,1P],8V:1e(1K,8W){1K=1a.8Y(1K);1c(18 i=0;i<4;++i)1K[i]=1a.7K[1K[i]];1K[0]=1K[0]^1a.8X[8W];1d 1K},85:1e(1k,1g){18 89=(16*(1a.7I(1g)+1));18 34=0;18 8U=1;18 t=[];18 1m=[];1c(18 i=0;i<89;i++)1m[i]=0;1c(18 j=0;j<1g;j++)1m[j]=1k[j];34+=1g;7r(34<89){1c(18 k=0;k<4;k++)t[k]=1m[(34-4)+k];1f(34%1g==0)t=1a.8V(t,8U++);1f(1g==1a.7j.86&&((34%1g)==16))1c(18 l=0;l<4;l++)t[l]=1a.7K[t[l]];1c(18 m=0;m<4;m++){1m[34]=1m[34-1g]^t[m];34++}}1d 1m},6D:1e(1b,31){1c(18 i=0;i<16;i++)1b[i]^=31[i];1d 1b},6C:1e(1m,8T){18 31=[];1c(18 i=0;i<4;i++)1c(18 j=0;j<4;j++)31[j*4+i]=1m[8T+i*4+j];1d 31},7k:1e(1b,2V){1c(18 i=0;i<16;i++)1b[i]=2V?1a.8S[1b[i]]:1a.7K[1b[i]];1d 1b},7l:1e(1b,2V){1c(18 i=0;i<4;i++)1b=1a.8R(1b,i*4,i,2V);1d 1b},8R:1e(1b,33,8Q,2V){1c(18 i=0;i<8Q;i++){1f(2V){18 7J=1b[33+3];1c(18 j=3;j>0;j--)1b[33+j]=1b[33+j-1];1b[33]=7J}1n{18 7J=1b[33];1c(18 j=0;j<3;j++)1b[33+j]=1b[33+j+1];1b[33+3]=7J}}1d 1b},1z:1e(a,b){18 p=0;1c(18 88=0;88<8;88++){1f((b&1)==1)p^=a;1f(p>3a)p^=3a;18 8P=(a&1x);a<<=1;1f(a>3a)a^=3a;1f(8P==1x)a^=1J;1f(a>3a)a^=3a;b>>=1;1f(b>3a)b^=3a;}1d p},87:1e(1b,2V){18 2J=[];1c(18 i=0;i<4;i++){1c(18 j=0;j<4;j++)2J[j]=1b[(j*4)+i];2J=1a.8O(2J,2V);1c(18 k=0;k<4;k++)1b[(k*4)+i]=2J[k]}1d 1b},8O:1e(2J,2V){18 1q=[];1f(2V)1q=[14,9,13,11];1n 1q=[2,1,1,3];18 1s=[];1c(18 i=0;i<4;i++)1s[i]=2J[i];2J[0]=1a.1z(1s[0],1q[0])^1a.1z(1s[3],1q[1])^1a.1z(1s[2],1q[2])^1a.1z(1s[1],1q[3]);2J[1]=1a.1z(1s[1],1q[0])^1a.1z(1s[0],1q[1])^1a.1z(1s[3],1q[2])^1a.1z(1s[2],1q[3]);2J[2]=1a.1z(1s[2],1q[0])^1a.1z(1s[1],1q[1])^1a.1z(1s[0],1q[2])^1a.1z(1s[3],1q[3]);2J[3]=1a.1z(1s[3],1q[0])^1a.1z(1s[2],1q[1])^1a.1z(1s[1],1q[2])^1a.1z(1s[0],1q[3]);1d 2J},8N:1e(1b,31){1b=1a.7k(1b,2N);1b=1a.7l(1b,2N);1b=1a.87(1b,2N);1b=1a.6D(1b,31);1d 1b},8M:1e(1b,31){1b=1a.7l(1b,37);1b=1a.7k(1b,37);1b=1a.6D(1b,31);1b=1a.87(1b,37);1d 1b},8J:1e(1b,1m,1D){1b=1a.6D(1b,1a.6C(1m,0));1c(18 i=1;i<1D;i++)1b=1a.8N(1b,1a.6C(1m,16*i));1b=1a.7k(1b,2N);1b=1a.7l(1b,2N);1b=1a.6D(1b,1a.6C(1m,16*1D));1d 1b},8I:1e(1b,1m,1D){1b=1a.6D(1b,1a.6C(1m,16*1D));1c(18 i=1D-1;i>0;i--)1b=1a.8M(1b,1a.6C(1m,16*i));1b=1a.7l(1b,37);1b=1a.7k(1b,37);1b=1a.6D(1b,1a.6C(1m,0));1d 1b},7I:1e(1g){18 1D;8m(1g){6A 1a.7j.8L:1D=10;36;6A 1a.7j.8K:1D=12;36;6A 1a.7j.86:1D=14;36;aB:1d 2Y;36}1d 1D},2P:1e(1r,1k,1g){18 1j=[];18 2U=[];18 1D=1a.7I(1g);1c(18 i=0;i<4;i++)1c(18 j=0;j<4;j++)2U[(i+(j*4))]=1r[(i*4)+j];18 1m=1a.85(1k,1g);2U=1a.8J(2U,1m,1D);1c(18 k=0;k<4;k++)1c(18 l=0;l<4;l++)1j[(k*4)+l]=2U[(k+(l*4))];1d 1j},81:1e(1r,1k,1g){18 1j=[];18 2U=[];18 1D=1a.7I(1g);1c(18 i=0;i<4;i++)1c(18 j=0;j<4;j++)2U[(i+(j*4))]=1r[(i*4)+j];18 1m=1a.85(1k,1g);2U=1a.8I(2U,1m,1D);1c(18 k=0;k<4;k++)1c(18 l=0;l<4;l++)1j[(k*4)+l]=2U[(k+(l*4))];1d 1j}},38:{82:0,83:1,7H:2},84:1e(2Z,1G,1C,1I){1f(1C-1G>16)1C=1G+16;18 2M=2Z.7B(1G,1C);1f(1I==1a.38.7H){18 8H=16-2M.1h;7r(2M.1h<16){2M.1o(8H)}}1d 2M},2P:1e(2Z,1I,1k,1g,2I){1f(1k.1h%1g){6B\'8G 1h 8F 8E 8D 8C 1g.\'}1f(2I.1h%16){6B\'2I 1h 8B 8A 2Q 8z.\'}18 1p=[];18 1r=[];18 1j=[];18 1B=[];18 7i=[];18 1H=37;1f(2Z!==2Y){1c(18 j=0;j<6I.7A(2Z.1h/16);j++){18 1G=j*16;18 1C=j*16+16;1f(j*16+16>2Z.1h)1C=2Z.1h;1p=1a.84(2Z,1G,1C,1I);1f(1I==1a.38.83){1f(1H){1j=1a.2O.2P(2I,1k,1g);1H=2N}1n 1j=1a.2O.2P(1r,1k,1g);1c(18 i=0;i<16;i++)1B[i]=1p[i]^1j[i];1c(18 k=0;k<1C-1G;k++)7i.1o(1B[k]);1r=1B}1n 1f(1I==1a.38.82){1f(1H){1j=1a.2O.2P(2I,1k,1g);1H=2N}1n 1j=1a.2O.2P(1r,1k,1g);1c(18 i=0;i<16;i++)1B[i]=1p[i]^1j[i];1c(18 k=0;k<1C-1G;k++)7i.1o(1B[k]);1r=1j}1n 1f(1I==1a.38.7H){1c(18 i=0;i<16;i++)1r[i]=1p[i]^((1H)?2I[i]:1B[i]);1H=2N;1B=1a.2O.2P(1r,1k,1g);1c(18 k=0;k<16;k++)7i.1o(1B[k])}}}1d{1I:1I,7G:2Z.1h,aA:7i}},81:1e(6L,7G,1I,1k,1g,2I){1f(1k.1h%1g){6B\'8G 1h 8F 8E 8D 8C 1g.\';1d 2Y}1f(2I.1h%16){6B\'2I 1h 8B 8A 2Q 8z.\'}18 1B=[];18 1r=[];18 1j=[];18 1p=[];18 6K=[];18 1H=37;1f(6L!==2Y){1c(18 j=0;j<6I.7A(6L.1h/16);j++){18 1G=j*16;18 1C=j*16+16;1f(j*16+16>6L.1h)1C=6L.1h;1B=1a.84(6L,1G,1C,1I);1f(1I==1a.38.83){1f(1H){1j=1a.2O.2P(2I,1k,1g);1H=2N}1n 1j=1a.2O.2P(1r,1k,1g);1c(i=0;i<16;i++)1p[i]=1j[i]^1B[i];1c(18 k=0;k<1C-1G;k++)6K.1o(1p[k]);1r=1B}1n 1f(1I==1a.38.82){1f(1H){1j=1a.2O.2P(2I,1k,1g);1H=2N}1n 1j=1a.2O.2P(1r,1k,1g);1c(i=0;i<16;i++)1p[i]=1j[i]^1B[i];1c(18 k=0;k<1C-1G;k++)6K.1o(1p[k]);1r=1j}1n 1f(1I==1a.38.7H){1j=1a.2O.81(1B,1k,1g);1c(i=0;i<16;i++)1p[i]=((1H)?2I[i]:1r[i])^1j[i];1H=2N;1f(7G<1C)1c(18 k=0;k<7G-1G;k++)6K.1o(1p[k]);1n 1c(18 k=0;k<1C-1G;k++)6K.1o(1p[k]);1r=1B}}}1d 6K}};18 7x={8y:1e(s){8x{1d az(ay(s))}8w(e){6B\'7Y 7X 8v ax: 7x.8y.\'}},8u:1e(s){8x{1d aw(av(s))}8w(e){6B(\'7Y 7X 8v 8q: 7x.8u.\')}},au:1e(){18 2M=[];1f(7F.1h==1&&7F[0].as==73)2M=7F[0];1n 2M=7F;18 6J=\'\';1c(18 i=0;i<2M.1h;i++)6J+=(2M[i]<16?\'0\':\'\')+2M[i].74(16);1d 6J.7L()},ar:1e(s){18 6J=[];s.7n(/(..)/g,1e(s){6J.1o(aq(s,16))});1d 6J},8t:1e(7D,7E){1f(7D===2Y)7D=0;1f(7E===2Y)7E=1;1d 6I.ap(6I.ao()*(7E+1))+7D},an:1e(7C){1f(7C===2Y)7C=16;18 1k=[];1c(18 i=0;i<7C*2;i++)1k.1o(1a.8t(0,8j));1d 1k},am:1e(s,1g){18 8s=al.ak.aj(s);1d 8s.7B(0,1g)},ai:1e(s){18 1p=[];1c(18 i=0;i<s.1h;i++){1p.1o(s.1E(i))}1d 1p},ah:1e(1p){18 s=\'\';1c(18 i=0;i<1p.1h;i++){s+=1N.1M(1p[i])}1d s},7W:{2X:[\'A\',\'B\',\'C\',\'D\',\'E\',\'F\',\'G\',\'H\',\'I\',\'J\',\'K\',\'L\',\'M\',\'N\',\'O\',\'P\',\'Q\',\'R\',\'S\',\'T\',\'U\',\'V\',\'W\',\'X\',\'Y\',\'Z\',\'a\',\'b\',\'c\',\'d\',\'e\',\'f\',\'g\',\'h\',\'i\',\'j\',\'k\',\'l\',\'m\',\'n\',\'o\',\'p\',\'q\',\'r\',\'s\',\'t\',\'u\',\'v\',\'w\',\'x\',\'y\',\'z\',\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\',\'+\',\'/\',\'=\'],8r:1e(1y){18 1O=\'\';1c(18 i=0;i<1y.1h;i+=3){1O+=1a.2X[1y[i]>>2];1O+=1a.2X[((1y[i]&3)<<4)|(1y[i+1]>>4)];1f(!(1y[i+1]===2Y)){1O+=1a.2X[((1y[i+1]&15)<<2)|(1y[i+2]>>6)]}1n{1O+=\'=\'}1f(!(1y[i+2]===2Y)){1O+=1a.2X[1y[i+2]&63]}1n{1O+=\'=\'}}1d 1O},ag:1e(1y){18 1O=1a.8r(1y);18 7Z=1O.7B(0,64)+\'\\n\';1c(18 i=1;i<(6I.7A(1O.1h/64));i++){7Z+=1O.7B(i*64,i*64+64)+(6I.7A(1O.1h/64)==i+1?\'\':\'\\n\')}1d 7Z},8p:1e(1i){1i=1i.7n(/[\\r\\n\\t ]+/g,\'\')+\'====\';18 1y=[];18 c=[];1c(18 i=0;37;i=i+4){c[0]=1a.2X.7z(1i.7y(i));1f(c[0]==64){1d 1y}c[1]=1a.2X.7z(1i.7y(i+1));c[2]=1a.2X.7z(1i.7y(i+2));c[3]=1a.2X.7z(1i.7y(i+3));1f((c[0]<0)||(c[1]<0)||(c[1]==64)||(c[2]<0)||(c[3]<0)){6B\'7Y 7X 7W 8q at af \'+i+\': 7x.7W.8p.\'}1y.1o((c[0]<<2)|(c[1]>>4));1f(c[2]>=0&&c[2]<64){1y.1o(((c[1]&15)<<4)|(c[2]>>2));1f(c[3]>=0&&c[2]<64){1y.1o(((c[2]&3)<<6)|c[3])}}}}}};1e ae(1F){1e 2T(n,s){18 8o=(n<<s)|(n>>>(32-s));1d 8o};1e ad(7h){18 6H="";18 i;18 7V;18 7U;1c(i=0;i<=6;i+=2){7V=(7h>>>(i*4+4))&2L;7U=(7h>>>(i*4))&2L;6H+=7V.74(16)+7U.74(16)}1d 6H};1e 6G(7h){18 6H="";18 i;18 v;1c(i=7;i>=0;i--){v=(7h>>>(i*4))&2L;6H+=v.74(16)}1d 6H};1e 7m(1i){1i=1i.7n(/\\r\\n/g,"\\n");18 1A="";1c(18 n=0;n<1i.1h;n++){18 c=1i.1E(n);1f(c<2Q){1A+=1N.1M(c)}1n 1f((c>8i)&&(c<8h)){1A+=1N.1M((c>>6)|8g);1A+=1N.1M((c&63)|2Q)}1n{1A+=1N.1M((c>>12)|8f);1A+=1N.1M(((c>>6)&63)|2Q);1A+=1N.1M((c&63)|2Q)}}1d 1A};18 7g;18 i,j;18 W=8n 73(80);18 7f=8d;18 7e=8c;18 7d=8b;18 7c=8a;18 7b=ab;18 A,B,C,D,E;18 1L;1F=7m(1F);18 2K=1F.1h;18 2W=8n 73();1c(i=0;i<2K-3;i+=4){j=1F.1E(i)<<24|1F.1E(i+1)<<16|1F.1E(i+2)<<8|1F.1E(i+3);2W.1o(j)}8m(2K%4){6A 0:i=aa;36;6A 1:i=1F.1E(2K-1)<<24|a9;36;6A 2:i=1F.1E(2K-2)<<24|1F.1E(2K-1)<<16|a8;36;6A 3:i=1F.1E(2K-3)<<24|1F.1E(2K-2)<<16|1F.1E(2K-1)<<8|1x;36}2W.1o(i);7r((2W.1h%16)!=14)2W.1o(0);2W.1o(2K>>>29);2W.1o((2K<<3)&2S);1c(7g=0;7g<2W.1h;7g+=16){1c(i=0;i<16;i++)W[i]=2W[7g+i];1c(i=16;i<=79;i++)W[i]=2T(W[i-3]^W[i-8]^W[i-14]^W[i-16],1);A=7f;B=7e;C=7d;D=7c;E=7b;1c(i=0;i<=19;i++){1L=(2T(A,5)+((B&C)|(~B&D))+E+W[i]+a7)&2S;E=D;D=C;C=2T(B,30);B=A;A=1L}1c(i=20;i<=39;i++){1L=(2T(A,5)+(B^C^D)+E+W[i]+a6)&2S;E=D;D=C;C=2T(B,30);B=A;A=1L}1c(i=40;i<=59;i++){1L=(2T(A,5)+((B&C)|(B&D)|(C&D))+E+W[i]+a5)&2S;E=D;D=C;C=2T(B,30);B=A;A=1L}1c(i=60;i<=79;i++){1L=(2T(A,5)+(B^C^D)+E+W[i]+a4)&2S;E=D;D=C;C=2T(B,30);B=A;A=1L}7f=(7f+A)&2S;7e=(7e+B)&2S;7d=(7d+C)&2S;7c=(7c+D)&2S;7b=(7b+E)&2S}18 1L=6G(7f)+6G(7e)+6G(7d)+6G(7c)+6G(7b);1d 1L.7L()}18 a3=1e(1i){1e 7a(76,7T){1d(76<<7T)|(76>>>(32-7T))}1e 1l(7w,7v){18 7u,7t,6F,6E,6z;6F=(7w&7S);6E=(7v&7S);7u=(7w&7s);7t=(7v&7s);6z=(7w&8l)+(7v&8l);1f(7u&7t){1d(6z^7S^6F^6E)}1f(7u|7t){1f(6z&7s){1d(6z^a2^6F^6E)}1n{1d(6z^7s^6F^6E)}}1n{1d(6z^6F^6E)}}1e F(x,y,z){1d(x&y)|((~x)&z)}1e G(x,y,z){1d(x&z)|(y&(~z))}1e H(x,y,z){1d(x^y^z)}1e I(x,y,z){1d(y^(x|(~z)))}1e 1w(a,b,c,d,x,s,ac){a=1l(a,1l(1l(F(b,c,d),x),ac));1d 1l(7a(a,s),b)};1e 1v(a,b,c,d,x,s,ac){a=1l(a,1l(1l(G(b,c,d),x),ac));1d 1l(7a(a,s),b)};1e 1u(a,b,c,d,x,s,ac){a=1l(a,1l(1l(H(b,c,d),x),ac));1d 1l(7a(a,s),b)};1e 1t(a,b,c,d,x,s,ac){a=1l(a,1l(1l(I(b,c,d),x),ac));1d 1l(7a(a,s),b)};1e 8e(1i){18 6y;18 77=1i.1h;18 7R=77+8;18 8k=(7R-(7R%64))/64;18 7q=(8k+1)*16;18 35=73(7q-1);18 78=0;18 2R=0;7r(2R<77){6y=(2R-(2R%4))/4;78=(2R%4)*8;35[6y]=(35[6y]|(1i.1E(2R)<<78));2R++}6y=(2R-(2R%4))/4;78=(2R%4)*8;35[6y]=35[6y]|(1x<<78);35[7q-2]=77<<3;35[7q-1]=77>>>29;1d 35};1e 6M(76){18 7o="",7p="",7Q,75;1c(75=0;75<=3;75++){7Q=(76>>>(75*8))&8j;7p="0"+7Q.74(16);7o=7o+7p.a1(7p.1h-2,2)}1d 7o};1e 7m(1i){1i=1i.7n(/\\r\\n/g,"\\n");18 1A="";1c(18 n=0;n<1i.1h;n++){18 c=1i.1E(n);1f(c<2Q){1A+=1N.1M(c)}1n 1f((c>8i)&&(c<8h)){1A+=1N.1M((c>>6)|8g);1A+=1N.1M((c&63)|2Q)}1n{1A+=1N.1M((c>>12)|8f);1A+=1N.1M(((c>>6)&63)|2Q);1A+=1N.1M((c&63)|2Q)}}1d 1A};18 x=73();18 k,7P,7O,7N,7M,a,b,c,d;18 72=7,71=12,70=17,6Z=22;18 6Y=5,6X=9,6W=14,6V=20;18 6U=4,6T=11,6S=16,6R=23;18 6Q=6,6P=10,6O=15,6N=21;1i=7m(1i);x=8e(1i);a=8d;b=8c;c=8b;d=8a;1c(k=0;k<x.1h;k+=16){7P=a;7O=b;7N=c;7M=d;a=1w(a,b,c,d,x[k+0],72,a0);d=1w(d,a,b,c,x[k+1],71,9Z);c=1w(c,d,a,b,x[k+2],70,9Y);b=1w(b,c,d,a,x[k+3],6Z,9X);a=1w(a,b,c,d,x[k+4],72,9W);d=1w(d,a,b,c,x[k+5],71,9V);c=1w(c,d,a,b,x[k+6],70,9U);b=1w(b,c,d,a,x[k+7],6Z,9T);a=1w(a,b,c,d,x[k+8],72,9S);d=1w(d,a,b,c,x[k+9],71,9R);c=1w(c,d,a,b,x[k+10],70,9Q);b=1w(b,c,d,a,x[k+11],6Z,9P);a=1w(a,b,c,d,x[k+12],72,9O);d=1w(d,a,b,c,x[k+13],71,9N);c=1w(c,d,a,b,x[k+14],70,9M);b=1w(b,c,d,a,x[k+15],6Z,9L);a=1v(a,b,c,d,x[k+1],6Y,9K);d=1v(d,a,b,c,x[k+6],6X,9J);c=1v(c,d,a,b,x[k+11],6W,9I);b=1v(b,c,d,a,x[k+0],6V,9H);a=1v(a,b,c,d,x[k+5],6Y,9G);d=1v(d,a,b,c,x[k+10],6X,9F);c=1v(c,d,a,b,x[k+15],6W,9E);b=1v(b,c,d,a,x[k+4],6V,9D);a=1v(a,b,c,d,x[k+9],6Y,9C);d=1v(d,a,b,c,x[k+14],6X,9B);c=1v(c,d,a,b,x[k+3],6W,9A);b=1v(b,c,d,a,x[k+8],6V,9z);a=1v(a,b,c,d,x[k+13],6Y,9y);d=1v(d,a,b,c,x[k+2],6X,9x);c=1v(c,d,a,b,x[k+7],6W,9w);b=1v(b,c,d,a,x[k+12],6V,9v);a=1u(a,b,c,d,x[k+5],6U,9u);d=1u(d,a,b,c,x[k+8],6T,9t);c=1u(c,d,a,b,x[k+11],6S,9s);b=1u(b,c,d,a,x[k+14],6R,9r);a=1u(a,b,c,d,x[k+1],6U,9q);d=1u(d,a,b,c,x[k+4],6T,9p);c=1u(c,d,a,b,x[k+7],6S,9o);b=1u(b,c,d,a,x[k+10],6R,9n);a=1u(a,b,c,d,x[k+13],6U,9m);d=1u(d,a,b,c,x[k+0],6T,9l);c=1u(c,d,a,b,x[k+3],6S,9k);b=1u(b,c,d,a,x[k+6],6R,9j);a=1u(a,b,c,d,x[k+9],6U,9i);d=1u(d,a,b,c,x[k+12],6T,9h);c=1u(c,d,a,b,x[k+15],6S,9g);b=1u(b,c,d,a,x[k+2],6R,9f);a=1t(a,b,c,d,x[k+0],6Q,9e);d=1t(d,a,b,c,x[k+7],6P,9d);c=1t(c,d,a,b,x[k+14],6O,9c);b=1t(b,c,d,a,x[k+5],6N,9b);a=1t(a,b,c,d,x[k+12],6Q,9a);d=1t(d,a,b,c,x[k+3],6P,99);c=1t(c,d,a,b,x[k+10],6O,98);b=1t(b,c,d,a,x[k+1],6N,97);a=1t(a,b,c,d,x[k+8],6Q,96);d=1t(d,a,b,c,x[k+15],6P,95);c=1t(c,d,a,b,x[k+6],6O,94);b=1t(b,c,d,a,x[k+13],6N,93);a=1t(a,b,c,d,x[k+4],6Q,92);d=1t(d,a,b,c,x[k+11],6P,91);c=1t(c,d,a,b,x[k+2],6O,90);b=1t(b,c,d,a,x[k+9],6N,8Z);a=1l(a,7P);b=1l(b,7O);c=1l(c,7N);d=1l(d,7M)}18 1L=6M(a)+6M(b)+6M(c)+6M(d);1d 1L.7L()}',62,665,'||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||var||this|state|for|return|function|if|size|length|string|output|key|AddUnsigned|expandedKey|else|push|byteArray|mult|input|cpy|II|HH|GG|FF|0x80|flatArr|galois_multiplication|utftext|ciphertext|end|nbrRounds|charCodeAt|msg|start|firstRound|mode|0x1b|word|temp|fromCharCode|String|b64|0x8d|0x83|0x91|0x9f|0xef|0xc5|0xcb|0x63|0x1d|0x01|0x25||||||0x39|0x4a|0x72|0x3a||0x10|0x02|0xc6|0xd4|0x20|0x04|0x5e|0x66|0x74|0xe4|0x94|0x9a|0x97|0xb3|0xbd|0xcc|0xc2|0xfa|0xe8|0xbc|0x08|0x40|0x6a|0x2f|0x33|0x4d|0xd3|0x61|0x7d|0x35|0xab|0xd8|0x6c|0x36|iv|column|msg_len|0x0f|array|false|aes|encrypt|128|lByteCount|0x0ffffffff|rotate_left|block|isInv|word_array|chars|null|bytesIn||roundKey||statePointer|currentSize|lWordArray|break|true|modeOfOperation||0x100|0xb5|0xbb|0xa9|0xa7|0xfd|0xf3|0xe1|0xd9|0xd7|0x6d|0x71|0x7f|0x55|0x5b|0x49|0x47|0x13|0x2b|0x37|0x56|0x58|0x44|0x6e|0x60|0x7c|0x26|0x28|0x34|0x1e|0x0c|0xb6|0xb8|0xaa|0xa4|0x8e|0x92|0x9c|0xc8|0xda|0xfe|0xf0|0xe2|0xec|0x2e|0x3c|0x32|0x18|0x16|0x0a|0x50|0x4c||0x42|0x68|0x7a|0xc0|0xce|0xdc|0xd2|0xf8|0xf6|0xea|0xb0|0xbe|0xac|0xa2|0x88|0x86|0xfb|0xf5|0xe7|0xe9|0xc3|0xcd|0xdf|0xd1|0x8b|0x85|0x99|0xaf|0xa1|0x15|0x07|0x09|0x23|0x2d|0x3f|0x31|0x6b|0x65|0x77|0x79|0x53|0x5d|0x4f|0x41|0xd0|0xde|0xf4|0xe6|0xb2|0xa0|0xae|0x84|0x8a|0x98|0x96|0x2c|0x22|0x30|0x3e|0x14|0x1a|0x06|0x5c|0x52|0x4e|0x64|0x78|0x76|0x17|0x19||0x0b|0x05|0x21|0x3d|0x67|0x69|0x7b|0x75|0x5f|0x51|0x43|0xf7|0xf9|0xeb|0xe5|0xcf|0xc1|0xdd|0x87|0x89|0x9b|0x95|0xbf|0xb1|0xa3|0xad|0x6f|0x73|0x59|0x57|0x45|0x4b|0x11|0x1f|0x0d|0x03|0x29|0x27|0x3b|0x81|0x8f|0x9d|0x93|0xb9|0xb7|0xa5|0xf1|0xff|0xed|0xe3|0xc9|0xc7||0xd5|0xdb|||0xba|0xb4|0xa6|0xa8|0x82|0x8c|0x9e|0x90|0xca|0xc4|0xd6|0xf2|0xfc|0xee|0xe0|0x5a|0x54|0x46|0x48|0x62|0x7e|0x70|0x2a|0x24|0x38|0x12|0x1c|0x0e|0x00|lWordCount|lResult|case|throw|createRoundKey|addRoundKey|lY8|lX8|cvt_hex|str|Math|ret|bytesOut|cipherIn|WordToHex|S44|S43|S42|S41|S34|S33|S32|S31|S24|S23|S22|S21|S14|S13|S12|S11|Array|toString|lCount|lValue|lMessageLength|lBytePosition||RotateLeft|H4|H3|H2|H1|H0|blockstart|val|cipherOut|keySize|subBytes|shiftRows|Utf8Encode|replace|WordToHexValue|WordToHexValue_temp|lNumberOfWords|while|0x40000000|lY4|lX4|lY|lX|cryptoHelpers|charAt|indexOf|ceil|slice|len|min|max|arguments|originalsize|CBC|numberOfRounds|tmp|sbox|toLowerCase|DD|CC|BB|AA|lByte|lNumberOfWords_temp1|0x80000000|iShiftBits|vl|vh|base64|during|error|broken_b64||decrypt|OFB|CFB|getPaddedBlock|expandKey|SIZE_256|mixColumns|counter|expandedKeySize|0x10325476|0x98BADCFE|0xEFCDAB89|0x67452301|ConvertToWordArray|224|192|2048|127|255|lNumberOfWords_temp2|0x3FFFFFFF|switch|new|t4|decode|decoding|encode_line|sha|getRandom|decode_utf8|utf8|catch|try|encode_utf8|bits|be|must|specified|match|not|does|Key|cpad|invMain|main|SIZE_192|SIZE_128|invRound|round|mixColumn|hi_bit_set|nbr|shiftRow|rsbox|roundKeyPointer|rconIteration|core|iteration|Rcon|rotate|0xEB86D391|0x2AD7D2BB|0xBD3AF235|0xF7537E82|0x4E0811A1|0xA3014314|0xFE2CE6E0|0x6FA87E4F|0x85845DD1|0xFFEFF47D|0x8F0CCC92|0x655B59C3|0xFC93A039|0xAB9423A7|0x432AFF97|0xF4292244|0xC4AC5665|0x1FA27CF8|0xE6DB99E5|0xD9D4D039|0x4881D05|0xD4EF3085|0xEAA127FA|0x289B7EC6|0xBEBFBC70|0xF6BB4B60|0x4BDECFA9|0xA4BEEA44|0xFDE5380C|0x6D9D6122|0x8771F681|0xFFFA3942|0x8D2A4C8A|0x676F02D9|0xFCEFA3F8|0xA9E3E905|0x455A14ED|0xF4D50D87|0xC33707D6|0x21E1CDE6|0xE7D3FBC8|0xD8A1E681|0x2441453|0xD62F105D|0xE9B6C7AA|0x265E5A51|0xC040B340|0xF61E2562|0x49B40821|0xA679438E|0xFD987193|0x6B901122|0x895CD7BE|0xFFFF5BB1|0x8B44F7AF|0x698098D8|0xFD469501|0xA8304613|0x4787C62A|0xF57C0FAF|0xC1BDCEEE|0x242070DB|0xE8C7B756|0xD76AA478|substr|0xC0000000|MD5|0xCA62C1D6|0x8F1BBCDC|0x6ED9EBA1|0x5A827999|0x08000|0x0800000|0x080000000|0xC3D2E1F0||lsb_hex|SHA1|pos|encode|convertByteArrayToString|convertStringToByteArray|arr_sha256|sha2|jsHash|generatePrivateKey|generateSharedKey|random|floor|parseInt|toNumbers|constructor||toHex|escape|decodeURIComponent|encoding|encodeURIComponent|unescape|cipher|default|GEX|GDX|GBX|G9X|G3X|G2X|slowAES'.split('|'),0,{}))
diff --git a/javascript/jsPacker/srp.min.js b/javascript/jsPacker/srp.min.js
index e1c9059..2b3a68c 100644
--- a/javascript/jsPacker/srp.min.js
+++ b/javascript/jsPacker/srp.min.js
@@ -1 +1 @@
-eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('E 1E(s){D 2v=8;D 7h=0;E 1f(x,y){D 4h=(x&4g)+(y&4g);D 7p=(x>>16)+(y>>16)+(4h>>16);F(7p<<16)|(4h&4g)}E S(X,n){F(X>>>n)|(X<<(32-n))}E R(X,n){F(X>>>n)}E 7l(x,y,z){F((x&y)^((~x)&z))}E 7j(x,y,z){F((x&y)^(x&z)^(y&z))}E 7k(x){F(S(x,2)^S(x,13)^S(x,22))}E 7m(x){F(S(x,6)^S(x,11)^S(x,25))}E 7n(x){F(S(x,7)^S(x,18)^R(x,3))}E 7o(x){F(S(x,17)^S(x,19)^R(x,10))}E 7d(m,l){D K=V 1w(bi,bh,bg,bf,bd,bc,bb,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0,aZ,aY,aX,aW,aV,aU,aT,aS,aR,aQ,aP,aO,aN,aM,aL,aK,aJ,aI,aH,aG,aF,aE,aD,aC,aB,aA,az,ay,ax,aw,av,au,at,as,ar,aq,ap,ao,an,al,ak,aj,ai,ah,ag,af,ae);D Z=V 1w(ad,ab,aa,a9,a8,a7,a6,a5);D W=V 1w(64);D a,b,c,d,e,f,g,h,i,j;D 3w,4f;m[l>>5]|=2P<<(24-l%32);m[((l+64>>9)<<4)+15]=l;P(D i=0;i<m.U;i+=16){a=Z[0];b=Z[1];c=Z[2];d=Z[3];e=Z[4];f=Z[5];g=Z[6];h=Z[7];P(D j=0;j<64;j++){C(j<16)W[j]=m[j+i];J W[j]=1f(1f(1f(7o(W[j-2]),W[j-7]),7n(W[j-15])),W[j-16]);3w=1f(1f(1f(1f(h,7m(e)),7l(e,f,g)),K[j]),W[j]);4f=1f(7k(a),7j(a,b,c));h=g;g=f;f=e;e=1f(d,3w);d=c;c=b;b=a;a=1f(3w,4f)}Z[0]=1f(a,Z[0]);Z[1]=1f(b,Z[1]);Z[2]=1f(c,Z[2]);Z[3]=1f(d,Z[3]);Z[4]=1f(e,Z[4]);Z[5]=1f(f,Z[5]);Z[6]=1f(g,Z[6]);Z[7]=1f(h,Z[7])}F Z}E 7c(1P){D 4e=1w();D 7i=(1<<2v)-1;P(D i=0;i<1P.U*2v;i+=2v){4e[i>>5]|=(1P.27(i/2v)&7i)<<(24-i%32)}F 4e}E 7f(2u){2u=2u.a4(/\\r\\n/g,"\\n");D 1T="";P(D n=0;n<2u.U;n++){D c=2u.27(n);C(c<3v){1T+=2x.2w(c)}J C((c>5U)&&(c<a3)){1T+=2x.2w((c>>6)|a2);1T+=2x.2w((c&63)|3v)}J{1T+=2x.2w((c>>12)|a1);1T+=2x.2w(((c>>6)&63)|3v);1T+=2x.2w((c&63)|3v)}}F 1T}E 7e(3u){D 4d=7h?"a0":"9Z";D 1P="";P(D i=0;i<3u.U*4;i++){1P+=4d.2R((3u[i>>2]>>((3-i%4)*8+4))&7g)+4d.2R((3u[i>>2]>>((3-i%4)*8))&7g)}F 1P}s=7f(s);F 7e(7d(7c(s),s.U*2v))}E 3t(){o.i=0;o.j=0;o.S=V 1w()}E 7b(2c){D i,j,t;P(i=0;i<1S;++i)o.S[i]=i;j=0;P(i=0;i<1S;++i){j=(j+o.S[i]+2c[i%2c.U])&1D;t=o.S[i];o.S[i]=o.S[j];o.S[j]=t}o.i=0;o.j=0}E 7a(){D t;o.i=(o.i+1)&1D;o.j=(o.j+o.S[o.i])&1D;t=o.S[o.i];o.S[o.i]=o.S[o.j];o.S[o.j]=t;F o.S[(t+o.S[o.i])&1D]}3t.H.74=7b;3t.H.72=7a;E 75(){F V 3t()}D 3s=1S;D 2V;D 1s;D 1g;E 78(x){1s[1g++]^=x&1D;1s[1g++]^=(x>>8)&1D;1s[1g++]^=(x>>16)&1D;1s[1g++]^=(x>>24)&1D;C(1g>=3s)1g-=3s}E 4c(){78(V 9Y().9X())}C(1s==1b){1s=V 1w();1g=0;D t;C(3r.49=="6V"&&3r.9W<"5"&&1U.77){D z=1U.77.76(32);P(t=0;t<z.U;++t)1s[1g++]=z.27(t)&1D}L(1g<3s){t=1e.1Z(9V*1e.76());1s[1g++]=t>>>8;1s[1g++]=t&1D}1g=0;4c();}E 70(){C(2V==1b){4c();2V=75();2V.74(1s);P(1g=0;1g<1s.U;++1g)1s[1g]=0;1g=0;}F 2V.72()}E 6Z(ba){D i;P(i=0;i<ba.U;++i)ba[i]=70()}E 3I(){}3I.H.6a=6Z;D 1L;D 6Y=9U;D 4a=((6Y&9T)==9S);E G(a,b,c){C(a!=1b)C("6b"==3g a)o.3M(a,b,c);J C(b==1b&&"2u"!=3g a)o.3m(a,1S);J o.3m(a,b)}E Q(){F V G(1b)}E 6U(i,x,w,j,c,n){L(--n>=0){D v=x*o[i++]+w[j]+c;c=1e.1Z(v/9R);w[j++]=v&9Q}F c}E 6W(i,x,w,j,c,n){D 2t=x&2S,2s=x>>15;L(--n>=0){D l=o[i]&2S;D h=o[i++]>>15;D m=2s*l+h*2t;l=2t*l+((m&2S)<<15)+w[j]+(c&6X);c=(l>>>30)+(m>>>15)+2s*h+(c>>>30);w[j++]=l&6X}F c}E 6T(i,x,w,j,c,n){D 2t=x&4b,2s=x>>14;L(--n>=0){D l=o[i]&4b;D h=o[i++]>>14;D m=2s*l+h*2t;l=2t*l+((m&4b)<<14)+w[j]+c;c=(l>>28)+(m>>14)+2s*h;w[j++]=l&9P}F c}C(4a&&(3r.49=="4K 9O 9N")){G.H.am=6W;1L=30}J C(4a&&(3r.49!="6V")){G.H.am=6U;1L=26}J{G.H.am=6T;1L=28}G.H.O=1L;G.H.1h=((1<<1L)-1);G.H.1m=(1<<1L);D 3q=52;G.H.6R=1e.2F(2,3q);G.H.45=3q-1L;G.H.42=2*1L-3q;D 6S="9M";D 2U=V 1w();D 2a,1r;2a="0".27(0);P(1r=0;1r<=9;++1r)2U[2a++]=1r;2a="a".27(0);P(1r=10;1r<36;++1r)2U[2a++]=1r;2a="A".27(0);P(1r=10;1r<36;++1r)2U[2a++]=1r;E 46(n){F 6S.2R(n)}E 3X(s,i){D c=2U[s.27(i)];F(c==1b)?-1:c}E 6z(r){P(D i=o.t-1;i>=0;--i)r[i]=o[i];r.t=o.t;r.s=o.s}E 6y(x){o.t=1;o.s=(x<0)?-1:0;C(x>0)o[0]=x;J C(x<-1)o[0]=x+1m;J o.t=0}E 1I(i){D r=Q();r.2j(i);F r}E 6x(s,b){D k;C(b==16)k=4;J C(b==8)k=3;J C(b==1S)k=8;J C(b==2)k=1;J C(b==32)k=5;J C(b==4)k=2;J{o.5O(s,b);F}o.t=0;o.s=0;D i=s.U,20=1t,1q=0;L(--i>=0){D x=(k==8)?s[i]&2O:3X(s,i);C(x<0){C(s.2R(i)=="-")20=1F;6c}20=1t;C(1q==0)o[o.t++]=x;J C(1q+k>o.O){o[o.t-1]|=(x&((1<<(o.O-1q))-1))<<1q;o[o.t++]=(x>>(o.O-1q))}J o[o.t-1]|=x<<1q;1q+=k;C(1q>=o.O)1q-=o.O}C(k==8&&(s[0]&2P)!=0){o.s=-1;C(1q>0)o[o.t-1]|=((1<<(o.O-1q))-1)<<1q}o.1n();C(20)G.1v.Y(o,o)}E 6w(){D c=o.s&o.1h;L(o.t>0&&o[o.t-1]==c)--o.t}E 6j(b){C(o.s<0)F"-"+o.2I().1z(b);D k;C(b==16)k=4;J C(b==8)k=3;J C(b==2)k=1;J C(b==32)k=5;J C(b==4)k=2;J F o.5Q(b);D 2K=(1<<k)-1,d,m=1t,r="",i=o.t;D p=o.O-(i*o.O)%k;C(i-->0){C(p<o.O&&(d=o[i]>>p)>0){m=1F;r=46(d)}L(i>=0){C(p<k){d=(o[i]&((1<<p)-1))<<(k-p);d|=o[--i]>>(p+=o.O-k)}J{d=(o[i]>>(p-=k))&2K;C(p<=0){p+=o.O;--i}}C(d>0)m=1F;C(m)r+=46(d)}}F m?r:"0"}E 6i(){D r=Q();G.1v.Y(o,r);F r}E 6h(){F(o.s<0)?o.2I():o}E 6g(a){D r=o.s-a.s;C(r!=0)F r;D i=o.t;r=i-a.t;C(r!=0)F r;L(--i>=0)C((r=o[i]-a[i])!=0)F r;F 0}E 2L(x){D r=1,t;C((t=x>>>16)!=0){x=t;r+=16}C((t=x>>8)!=0){x=t;r+=8}C((t=x>>4)!=0){x=t;r+=4}C((t=x>>2)!=0){x=t;r+=2}C((t=x>>1)!=0){x=t;r+=1}F r}E 6f(){C(o.t<=0)F 0;F o.O*(o.t-1)+2L(o[o.t-1]^(o.s&o.1h))}E 6v(n,r){D i;P(i=o.t-1;i>=0;--i)r[i+n]=o[i];P(i=n-1;i>=0;--i)r[i]=0;r.t=o.t+n;r.s=o.s}E 6u(n,r){P(D i=n;i<o.t;++i)r[i-n]=o[i];r.t=1e.3J(o.t-n,0);r.s=o.s}E 6t(n,r){D 1C=n%o.O;D 2r=o.O-1C;D 2T=(1<<2r)-1;D 1p=1e.1Z(n/o.O),c=(o.s<<1C)&o.1h,i;P(i=o.t-1;i>=0;--i){r[i+1p+1]=(o[i]>>2r)|c;c=(o[i]&2T)<<1C}P(i=1p-1;i>=0;--i)r[i]=0;r[1p]=c;r.t=o.t+1p+1;r.s=o.s;r.1n()}E 6s(n,r){r.s=o.s;D 1p=1e.1Z(n/o.O);C(1p>=o.t){r.t=0;F}D 1C=n%o.O;D 2r=o.O-1C;D 2T=(1<<1C)-1;r[0]=o[1p]>>1C;P(D i=1p+1;i<o.t;++i){r[i-1p-1]|=(o[i]&2T)<<2r;r[i-1p]=o[i]>>1C}C(1C>0)r[o.t-1p-1]|=(o.s&2T)<<2r;r.t=o.t-1p;r.1n()}E 6r(a,r){D i=0,c=0,m=1e.1N(a.t,o.t);L(i<m){c+=o[i]-a[i];r[i++]=c&o.1h;c>>=o.O}C(a.t<o.t){c-=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1h;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c-=a[i];r[i++]=c&o.1h;c>>=o.O}c-=a.s}r.s=(c<0)?-1:0;C(c<-1)r[i++]=o.1m+c;J C(c>0)r[i++]=c;r.t=i;r.1n()}E 6q(a,r){D x=o.1H(),y=a.1H();D i=x.t;r.t=i+y.t;L(--i>=0)r[i]=0;P(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.1n();C(o.s!=a.s)G.1v.Y(r,r)}E 6p(r){D x=o.1H();D i=r.t=2*x.t;L(--i>=0)r[i]=0;P(i=0;i<x.t-1;++i){D c=x.am(i,x[i],r,2*i,0,1);C((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.1m){r[i+x.t]-=x.1m;r[i+x.t+1]=1}}C(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.1n()}E 6o(m,q,r){D 21=m.1H();C(21.t<=0)F;D 3p=o.1H();C(3p.t<21.t){C(q!=1b)q.2j(0);C(r!=1b)o.1J(r);F}C(r==1b)r=Q();D y=Q(),40=o.s,6O=m.s;D 2q=o.O-2L(21[21.t-1]);C(2q>0){21.2k(2q,y);3p.2k(2q,r)}J{21.1J(y);3p.1J(r)}D 1B=y.t;D 3o=y[1B-1];C(3o==0)F;D 44=3o*(1<<o.45)+((1B>1)?y[1B-2]>>o.42:0);D 6Q=o.6R/44,6P=(1<<o.45)/44,e=1<<o.42;D i=r.t,j=i-1B,t=(q==1b)?Q():q;y.2o(j,t);C(r.1d(t)>=0){r[r.t++]=1;r.Y(t,r)}G.1u.2o(1B,t);t.Y(y,y);L(y.t<1B)y[y.t++]=0;L(--j>=0){D 3n=(r[--i]==3o)?o.1h:1e.1Z(r[i]*6Q+(r[i-1]+e)*6P);C((r[i]+=y.am(0,3n,r,j,0,1B))<3n){y.2o(j,t);r.Y(t,r);L(r[i]<--3n)r.Y(t,r)}}C(q!=1b){r.2N(1B,q);C(40!=6O)G.1v.Y(q,q)}r.t=1B;r.1n();C(2q>0)r.1j(2q,r);C(40<0)G.1v.Y(r,r)}E 6e(a){D r=Q();o.1H().1K(a,1b,r);C(o.s<0&&r.1d(G.1v)>0)a.Y(r,r);F r}E 1R(m){o.m=m}E 6N(x){C(x.s<0||x.1d(o.m)>=0)F x.3h(o.m);J F x}E 6M(x){F x}E 6L(x){x.1K(o.m,1b,x)}E 6K(x,y,r){x.2n(y,r);o.1x(r)}E 6J(x,r){x.2M(r);o.1x(r)}1R.H.2m=6N;1R.H.2l=6M;1R.H.1x=6L;1R.H.1W=6K;1R.H.1A=6J;E 6m(){C(o.t<1)F 0;D x=o[0];C((x&1)==0)F 0;D y=x&3;y=(y*(2-(x&3W)*y))&3W;y=(y*(2-(x&2O)*y))&2O;y=(y*(2-(((x&3l)*y)&3l)))&3l;y=(y*(2-x*y%o.1m))%o.1m;F(y>0)?o.1m-y:-y}E 1Q(m){o.m=m;o.3Z=m.6n();o.3Y=o.3Z&2S;o.6H=o.3Z>>15;o.6G=(1<<(m.O-15))-1;o.6I=2*m.t}E 6E(x){D r=Q();x.1H().2o(o.m.t,r);r.1K(o.m,1b,r);C(x.s<0&&r.1d(G.1v)>0)o.m.Y(r,r);F r}E 6D(x){D r=Q();x.1J(r);o.1x(r);F r}E 6C(x){L(x.t<=o.6I)x[x.t++]=0;P(D i=0;i<o.m.t;++i){D j=x[i]&2S;D 6F=(j*o.3Y+(((j*o.6H+(x[i]>>15)*o.3Y)&o.6G)<<15))&x.1h;j=i+o.m.t;x[j]+=o.m.am(0,6F,x,i,0,o.m.t);L(x[j]>=x.1m){x[j]-=x.1m;x[++j]++}}x.1n();x.2N(o.m.t,x);C(x.1d(o.m)>=0)x.Y(o.m,x)}E 6A(x,r){x.2M(r);o.1x(r)}E 6B(x,y,r){x.2n(y,r);o.1x(r)}1Q.H.2m=6E;1Q.H.2l=6D;1Q.H.1x=6C;1Q.H.1W=6B;1Q.H.1A=6A;E 6l(){F((o.t>0)?(o[0]&1):o.s)==0}E 6k(e,z){C(e>9L||e<1)F G.1u;D r=Q(),1c=Q(),g=z.2m(o),i=2L(e)-1;g.1J(r);L(--i>=0){z.1A(r,1c);C((e&(1<<i))>0)z.1W(1c,g,r);J{D t=r;r=1c;1c=t}}F z.2l(r)}E 6d(e,m){D z;C(e<1S||m.1l())z=V 1R(m);J z=V 1Q(m);F o.3S(e,z)}G.H.1J=6z;G.H.2j=6y;G.H.3m=6x;G.H.1n=6w;G.H.2o=6v;G.H.2N=6u;G.H.2k=6t;G.H.1j=6s;G.H.Y=6r;G.H.2n=6q;G.H.2M=6p;G.H.1K=6o;G.H.6n=6m;G.H.1l=6l;G.H.3S=6k;G.H.1z=6j;G.H.2I=6i;G.H.1H=6h;G.H.1d=6g;G.H.3Q=6f;G.H.3h=6e;G.H.5S=6d;G.1v=1I(0);G.1u=1I(1);E 5y(){D r=Q();o.1J(r);F r}E 5x(){C(o.s<0){C(o.t==1)F o[0]-o.1m;J C(o.t==0)F-1}J C(o.t==1)F o[0];J C(o.t==0)F 0;F((o[1]&((1<<(32-o.O))-1))<<o.O)|o[0]}E 5w(){F(o.t==0)?o.s:(o[0]<<24)>>24}E 5v(){F(o.t==0)?o.s:(o[0]<<16)>>16}E 5R(r){F 1e.1Z(1e.9K*o.O/1e.9J(r))}E 5u(){C(o.s<0)F-1;J C(o.t<=0||(o.t==1&&o[0]<=0))F 0;J F 1}E 5P(b){C(b==1b)b=10;C(o.1G()==0||b<2||b>36)F"0";D 2Q=o.3N(b);D a=1e.2F(b,2Q);D d=1I(a),y=Q(),z=Q(),r="";o.1K(d,y,z);L(y.1G()>0){r=(a+z.3K()).1z(b).9I(1)+r;y.1K(d,y,z)}F z.3K().1z(b)+r}E 5N(s,b){o.2j(0);C(b==1b)b=10;D 2Q=o.3N(b);D d=1e.2F(b,2Q),20=1t,j=0,w=0;P(D i=0;i<s.U;++i){D x=3X(s,i);C(x<0){C(s.2R(i)=="-"&&o.1G()==0)20=1F;6c}w=b*w+x;C(++j>=2Q){o.3L(d);o.2h(w,0);j=0;w=0}}C(j>0){o.3L(1e.2F(b,j));o.2h(w,0)}C(20)G.1v.Y(o,o)}E 5M(a,b,c){C("6b"==3g b){C(a<2)o.2j(1);J{o.3M(a,c);C(!o.5f(a-1))o.1V(G.1u.3i(a-1),3k,o);C(o.1l())o.2h(1,0);L(!o.4W(b)){o.2h(2,0);C(o.3Q()>a)o.Y(G.1u.3i(a-1),o)}}}J{D x=V 1w(),t=a&7;x.U=(a>>3)+1;b.6a(x);C(t>0)x[0]&=((1<<t)-1);J x[0]=0;o.3m(x,1S)}}E 5t(){D i=o.t,r=V 1w();r[0]=o.s;D p=o.O-(i*o.O)%8,d,k=0;C(i-->0){C(p<o.O&&(d=o[i]>>p)!=(o.s&o.1h)>>p)r[k++]=d|(o.s<<(o.O-p));L(i>=0){C(p<8){d=(o[i]&((1<<p)-1))<<(8-p);d|=o[--i]>>(p+=o.O-8)}J{d=(o[i]>>(p-=8))&2O;C(p<=0){p+=o.O;--i}}C((d&2P)!=0)d|=-1S;C(k==0&&(o.s&2P)!=(d&2P))++k;C(k>0||d!=o.s)r[k++]=d}}F r}E 5s(a){F(o.1d(a)==0)}E 5r(a){F(o.1d(a)<0)?o:a}E 5q(a){F(o.1d(a)>0)?o:a}E 5L(a,1Y,r){D i,f,m=1e.1N(a.t,o.t);P(i=0;i<m;++i)r[i]=1Y(o[i],a[i]);C(a.t<o.t){f=a.s&o.1h;P(i=m;i<o.t;++i)r[i]=1Y(o[i],f);r.t=o.t}J{f=o.s&o.1h;P(i=m;i<a.t;++i)r[i]=1Y(f,a[i]);r.t=a.t}r.s=1Y(o.s,a.s);r.1n()}E 69(x,y){F x&y}E 5p(a){D r=Q();o.1V(a,69,r);F r}E 3k(x,y){F x|y}E 5o(a){D r=Q();o.1V(a,3k,r);F r}E 3U(x,y){F x^y}E 5n(a){D r=Q();o.1V(a,3U,r);F r}E 3V(x,y){F x&~y}E 5m(a){D r=Q();o.1V(a,3V,r);F r}E 5l(){D r=Q();P(D i=0;i<o.t;++i)r[i]=o.1h&~o[i];r.t=o.t;r.s=~o.s;F r}E 5k(n){D r=Q();C(n<0)o.1j(-n,r);J o.2k(n,r);F r}E 5i(n){D r=Q();C(n<0)o.2k(-n,r);J o.1j(n,r);F r}E 68(x){C(x==0)F-1;D r=0;C((x&3l)==0){x>>=16;r+=16}C((x&2O)==0){x>>=8;r+=8}C((x&3W)==0){x>>=4;r+=4}C((x&3)==0){x>>=2;r+=2}C((x&1)==0)++r;F r}E 5h(){P(D i=0;i<o.t;++i)C(o[i]!=0)F i*o.O+68(o[i]);C(o.s<0)F o.t*o.O;F-1}E 66(x){D r=0;L(x!=0){x&=x-1;++r}F r}E 5g(){D r=0,x=o.s&o.1h;P(D i=0;i<o.t;++i)r+=66(o[i]^x);F r}E 5e(n){D j=1e.1Z(n/o.O);C(j>=o.t)F(o.s!=0);F((o[j]&(1<<(n%o.O)))!=0)}E 5K(n,1Y){D r=G.1u.3i(n);o.1V(r,1Y,r);F r}E 5d(n){F o.3j(n,3k)}E 5c(n){F o.3j(n,3V)}E 5b(n){F o.3j(n,3U)}E 5J(a,r){D i=0,c=0,m=1e.1N(a.t,o.t);L(i<m){c+=o[i]+a[i];r[i++]=c&o.1h;c>>=o.O}C(a.t<o.t){c+=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1h;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c+=a[i];r[i++]=c&o.1h;c>>=o.O}c+=a.s}r.s=(c<0)?-1:0;C(c>0)r[i++]=c;J C(c<-1)r[i++]=o.1m+c;r.t=i;r.1n()}E 5a(a){D r=Q();o.2H(a,r);F r}E 58(a){D r=Q();o.Y(a,r);F r}E 57(a){D r=Q();o.2n(a,r);F r}E 55(a){D r=Q();o.1K(a,r,1b);F r}E 54(a){D r=Q();o.1K(a,1b,r);F r}E 51(a){D q=Q(),r=Q();o.1K(a,q,r);F V 1w(q,r)}E 5I(n){o[o.t]=o.am(0,n-1,o,0,0,o.t);++o.t;o.1n()}E 5H(n,w){L(o.t<=w)o[o.t++]=0;o[w]+=n;L(o[w]>=o.1m){o[w]-=o.1m;C(++w>=o.t)o[o.t++]=0;++o[w]}}E 2p(){}E 3T(x){F x}E 65(x,y,r){x.2n(y,r)}E 62(x,r){x.2M(r)}2p.H.2m=3T;2p.H.2l=3T;2p.H.1W=65;2p.H.1A=62;E 4Y(e){F o.3S(e,V 2p())}E 5F(a,n,r){D i=1e.1N(o.t+a.t,n);r.s=0;r.t=i;L(i>0)r[--i]=0;D j;P(j=r.t-o.t;i<j;++i)r[i+o.t]=o.am(0,a[i],r,i,0,o.t);P(j=1e.1N(a.t,n);i<j;++i)o.am(0,a[i],r,i,0,n-i);r.1n()}E 5D(a,n,r){--n;D i=r.t=o.t+a.t-n;r.s=0;L(--i>=0)r[i]=0;P(i=1e.3J(n-o.t,0);i<a.t;++i)r[o.t+i-n]=o.am(n-i,a[i],r,0,0,o.t+i-n);r.1n();r.2N(1,r)}E 1X(m){o.1c=Q();o.3R=Q();G.1u.2o(2*m.t,o.1c);o.60=o.1c.56(m);o.m=m}E 5Z(x){C(x.s<0||x.t>2*o.m.t)F x.3h(o.m);J C(x.1d(o.m)<0)F x;J{D r=Q();x.1J(r);o.1x(r);F r}}E 5Y(x){F x}E 5X(x){x.2N(o.m.t-1,o.1c);C(x.t>o.m.t+1){x.t=o.m.t+1;x.1n()}o.60.5E(o.1c,o.m.t+1,o.3R);o.m.5G(o.3R,o.m.t+1,o.1c);L(x.1d(o.1c)<0)x.2h(1,o.m.t+1);x.Y(o.1c,x);L(x.1d(o.m)>=0)x.Y(o.m,x)}E 5V(x,r){x.2M(r);o.1x(r)}E 5W(x,y,r){x.2n(y,r);o.1x(r)}1X.H.2m=5Z;1X.H.2l=5Y;1X.H.1x=5X;1X.H.1W=5W;1X.H.1A=5V;E 50(e,m){D i=e.3Q(),k,r=1I(1),z;C(i<=0)F r;J C(i<18)k=1;J C(i<48)k=3;J C(i<9H)k=4;J C(i<9G)k=5;J k=6;C(i<8)z=V 1R(m);J C(m.1l())z=V 1X(m);J z=V 1Q(m);D g=V 1w(),n=3,2J=k-1,2K=(1<<k)-1;g[1]=z.2m(o);C(k>1){D 3P=Q();z.1A(g[1],3P);L(n<=2K){g[n]=Q();z.1W(3P,g[n-2],g[n]);n+=2}}D j=e.t-1,w,3O=1F,1c=Q(),t;i=2L(e[j])-1;L(j>=0){C(i>=2J)w=(e[j]>>(i-2J))&2K;J{w=(e[j]&((1<<(i+1))-1))<<(2J-i);C(j>0)w|=e[j-1]>>(o.O+i-2J)}n=k;L((w&1)==0){w>>=1;--n}C((i-=n)<0){i+=o.O;--j}C(3O){g[w].1J(r);3O=1t}J{L(n>1){z.1A(r,1c);z.1A(1c,r);n-=2}C(n>0)z.1A(r,1c);J{t=r;r=1c;1c=t}z.1W(1c,g[w],r)}L(j>=0&&(e[j]&(1<<i))==0){z.1A(r,1c);t=r;r=1c;1c=t;C(--i<0){i=o.O-1;--j}}}F z.2l(r)}E 4X(a){D x=(o.s<0)?o.2I():o.2G();D y=(a.s<0)?a.2I():a.2G();C(x.1d(y)<0){D t=x;x=y;y=t}D i=x.2g(),g=y.2g();C(g<0)F x;C(i<g)g=i;C(g>0){x.1j(g,x);y.1j(g,y)}L(x.1G()>0){C((i=x.2g())>0)x.1j(i,x);C((i=y.2g())>0)y.1j(i,y);C(x.1d(y)>=0){x.Y(y,x);x.1j(1,x)}J{y.Y(x,y);y.1j(1,y)}}C(g>0)y.2k(g,y);F y}E 5B(n){C(n<=0)F 0;D d=o.1m%n,r=(o.s<0)?n-1:0;C(o.t>0)C(d==0)r=o[0]%n;J P(D i=o.t-1;i>=0;--i)r=(d*r+o[i])%n;F r}E 4Z(m){D ac=m.1l();C((o.1l()&&ac)||m.1G()==0)F G.1v;D u=m.2G(),v=o.2G();D a=1I(1),b=1I(0),c=1I(0),d=1I(1);L(u.1G()!=0){L(u.1l()){u.1j(1,u);C(ac){C(!a.1l()||!b.1l()){a.2H(o,a);b.Y(m,b)}a.1j(1,a)}J C(!b.1l())b.Y(m,b);b.1j(1,b)}L(v.1l()){v.1j(1,v);C(ac){C(!c.1l()||!d.1l()){c.2H(o,c);d.Y(m,d)}c.1j(1,c)}J C(!d.1l())d.Y(m,d);d.1j(1,d)}C(u.1d(v)>=0){u.Y(v,u);C(ac)a.Y(c,a);b.Y(d,b)}J{v.Y(u,v);C(ac)c.Y(a,c);d.Y(b,d)}}C(v.1d(G.1u)!=0)F G.1v;C(d.1d(m)>=0)F d.3f(m);C(d.1G()<0)d.2H(m,d);J F d;C(d.1G()<0)F d.3E(m);J F d}D 1k=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,9F,9E,9D,9C,9B,5U,9A,9z,9y,9x,9w,9v,9u,9t,9s,9r,9q,9p,9o,9n,9m,9l,9k,9j,9i,9h,9g,9f,9e,9d,9c,9b,9a,99,98,96,95,94,93,92,91,90,8Z,8Y,8X,8W,8V,8U,8T,8S,8R,8Q,8P,8O,8N,8M,8L,8K,8J,8I,8H,8G,8F,8E,8D,8C,8B,8A,8z,8y,8x,8w];D 5T=(1<<26)/1k[1k.U-1];E 4V(t){D i,x=o.1H();C(x.t==1&&x[0]<=1k[1k.U-1]){P(i=0;i<1k.U;++i)C(x[0]==1k[i])F 1F;F 1t}C(x.1l())F 1t;i=1;L(i<1k.U){D m=1k[i],j=i+1;L(j<1k.U&&m<5T)m*=1k[j++];m=x.5C(m);L(i<j)C(m%1k[i++]==0)F 1t}F x.5A(t)}E 5z(t){D 2i=o.3f(G.1u);D k=2i.2g();C(k<=0)F 1t;D r=2i.5j(k);t=(t+1)>>1;C(t>1k.U)t=1k.U;D a=Q();P(D i=0;i<t;++i){a.2j(1k[i]);D y=a.2f(r,o);C(y.1d(G.1u)!=0&&y.1d(2i)!=0){D j=1;L(j++<k&&y.1d(2i)!=0){y=y.5S(2,o);C(y.1d(G.1u)==0)F 1t}C(y.1d(2i)!=0)F 1t}}F 1F}G.H.3N=5R;G.H.5Q=5P;G.H.5O=5N;G.H.3M=5M;G.H.1V=5L;G.H.3j=5K;G.H.2H=5J;G.H.3L=5I;G.H.2h=5H;G.H.5G=5F;G.H.5E=5D;G.H.5C=5B;G.H.5A=5z;G.H.2G=5y;G.H.3K=5x;G.H.8v=5w;G.H.8u=5v;G.H.1G=5u;G.H.8t=5t;G.H.8s=5s;G.H.1N=5r;G.H.3J=5q;G.H.8r=5p;G.H.8q=5o;G.H.8p=5n;G.H.8o=5m;G.H.2b=5l;G.H.3i=5k;G.H.5j=5i;G.H.2g=5h;G.H.8n=5g;G.H.5f=5e;G.H.8m=5d;G.H.8l=5c;G.H.8k=5b;G.H.3E=5a;G.H.3f=58;G.H.3D=57;G.H.56=55;G.H.8j=54;G.H.8i=51;G.H.2f=50;G.H.8h=4Z;G.H.2F=4Y;G.H.8g=4X;G.H.4W=4V;E 4k(4R,4Q,4S,4T){D 4U="8f";D N=V G(4U,16);D g=V G("2");D k=V G("8e",16);D 3H=V 3I();D a=V G(32,3H);D A=g.2f(a,N);L(A.3h(N)==0){a=V G(32,3H);A=g.2f(a,N)}D 3F=A.1z(16);D S=1b;D K=1b;D M=1b;D 3d=1b;D 2e=4T;D 4P=4S;D 1a=o;D 2X=1t;D I=4R;D p=4Q;D T=1b;o.8d=E(){F I};o.8c=E(){F T};o.8b=E(){F 2e};o.8a=E(){F g};o.88=E(){F N};o.87=E(s){F V G(1E(s+1E(I+":"+p)),16)};o.2C=E(1P){C(4P=="86"){F 1P}};o.2A=E(4O){F 4O.85.84};E 2z(4N){F(3g(1U[4N])!="82")};o.2B=E(4I,2E,4J){C(1U.4M)T=V 4M();J C(1U.4L){81{T=V 4L("4K.80")}7Z(e){}}J{1a.1y("4G 2b 7Y.");F}C(T){T.7X=4J;T.7W("7V",4I,1F);T.3G("4H-4o","7U/x-7T-7S-7R");T.3G("4H-U",2E.U);T.3G("7Q","7P");T.7O(2E)}J{1a.1y("4G 7N.")}};o.4p=E(){D 4F=2e+1a.2C("7M/");D 2E="I="+I+"&A="+3F;1a.2B(4F,2E,4E)};E 4E(){C(T.3b==4&&T.3a==39){C(T.1o.1i("r").U>0){D 1O=T.1o.1i("r")[0];C(!1O.1M("a")){3B(1O.1M("s"),1O.1M("B"),p);1a.2B(2e+1a.2C("4x/"),"M="+M,4y)}J 3c(1O.1M("s"),1O.1M("B"),1O.1M("a"),1O.1M("d"))}J C(T.1o.1i("2d").U>0)1a.1y(T.1o.1i("2d")[0])}};E 3B(s,2D,4C){D B=V G(2D,16);D 4D=2D;D u=V G(1E(3F+4D),16);D x=V G(1E(s+1E(I+":"+4C)),16);D 4B=k.3D(g.2f(x,N));D 4A=a.3E(u.3D(x));S=B.3f(4B).2f(4A,N);D 4z=A.1z(16)+B.1z(16)+S.1z(16);M=1E(4z);3d=1E(A.1z(16)+M+S.1z(16));};E 4y(){C(T.3b==4&&T.3a==39){C(T.1o.1i("M").U>0){C(1a.2A(T.1o.1i("M")[0])==3d){1a.4l();2X=1F}J 1a.1y("4t 2c 4s 2b 4r")}J C(T.1o.1i("2d").U>0)1a.1y(1a.2A(T.1o.1i("2d")[0]))}};E 3c(s,2D,3C,3A){4m();E 3z(){C(!2z("2Z")||!2z("35")){1U.4w(3z,10);F}C(3C=="7L")3e=2Z;J C(3C=="7K")3e=35;3y(3e(3A+p));3B(s,2D,3e(3A+p));1a.2B(2e+1a.2C("3c/4x/"),"M="+M,4v)};1U.4w(3z,10)};E 4v(){C(T.3b==4&&T.3a==39){C(T.1o.1i("M").U>0){C(1a.2A(T.1o.1i("M")[0])==3d){D 4u=2e+1a.2C("3c/7J/");1a.2B(4u,"p="+p,4q)}J 1a.1y("4t 2c 4s 2b 4r")}J C(T.1o.1i("2d").U>0){1a.1y(1a.2A(T.1o.1i("2d")[0]))}}};E 4q(){C(T.3b==4&&T.3a==39){C(T.1o.1i("7I").U>0)1a.4p();J 1a.1y("7H 7G 2b be 7F")}};E 34(4n){D 38=2W.7E(\'3x\');38.4o=\'7D/7C\';38.4i=4n;2W.1i(\'7B\')[0].7A(38)};E 4m(){C(2z("2Z")&&2z("35"))F;D 2y=1a.4j.7z("/");D 33=2y.7y(0,2y.U-1).7x("/");C(2y[2y.U-1]=="7w.1N.2Y")34(33+"/7v.1N.2Y");J{34(33+"/35.2Y");34(33+"/2Z.2Y")}}o.2c=E(){C(K==1b)C(2X){K=1E(S);F K}J 1a.1y("7u 7t 2b 7s 2X.");J F K};o.4l=E(){3y("7r 7q.")};o.1y=E(t){3y(t)}};4k.H.4j=2W.1i(\'3x\')[2W.1i(\'3x\').U-1].1M("4i");',62,701,'||||||||||||||||||||||||this||||||||||||||if|var|function|return|BigInteger|prototype||else||while|||DB|for|nbi|||xhr|length|new|||subTo|HASH|||||||||||that|null|r2|compareTo|Math|safe_add|rng_pptr|DM|getElementsByTagName|rShiftTo|lowprimes|isEven|DV|clamp|responseXML|ds|sh|vv|rng_pool|false|ONE|ZERO|Array|reduce|error_message|toString|sqrTo|ys|bs|255|SHA256|true|signum|abs|nbv|copyTo|divRemTo|dbits|getAttribute|min|response|str|Montgomery|Classic|256|utftext|window|bitwiseTo|mulTo|Barrett|op|floor|mi|pm||||||charCodeAt|||rr|not|key|error|url|modPow|getLowestSetBit|dAddOffset|n1|fromInt|lShiftTo|revert|convert|multiplyTo|dlShiftTo|NullExp|nsh|cbs|xh|xl|string|chrsz|fromCharCode|String|arr|isdefined|innerxml|ajaxRequest|paths|ephemeral|params|pow|clone|addTo|negate|k1|km|nbits|squareTo|drShiftTo|0xff|0x80|cs|charAt|0x7fff|bm|BI_RC|rng_state|document|authenticated|js|SHA1||||path|import_file|MD5|||scriptElt|200|status|readyState|upgrade|M2|hashfun|subtract|typeof|mod|shiftLeft|changeBit|op_or|0xffff|fromString|qd|y0|pt|BI_FP|navigator|rng_psize|Arcfour|binarray|128|T1|script|alert|do_upgrade|dsalt|calculations|algo|multiply|add|Astr|setRequestHeader|rng|SecureRandom|max|intValue|dMultiply|fromNumber|chunkSize|is1|g2|bitLength|q3|exp|nNop|op_xor|op_andnot|0xf|intAt|mpl|mp|ts||F2||yt|F1|int2char|||appName|j_lm|0x3fff|rng_seed_time|hex_tab|bin|T2|0xFFFF|lsw|src|srpPath|SRP|success|import_hashes|fname|type|identify|confirm_verifier|match|does|Server|auth_url|confirm_upgrade|setTimeout|authenticate|confirm_authentication|Mstr|aux|kgx|pass|Bstr|receive_salts|handshake_url|Ajax|Content|full_url|callback|Microsoft|ActiveXObject|XMLHttpRequest|variable|node|server|password|username|ser|base_url|Nstr|bnIsProbablePrime|isProbablePrime|bnGCD|bnPow|bnModInverse|bnModPow|bnDivideAndRemainder|||bnRemainder|bnDivide|divide|bnMultiply|bnSubtract||bnAdd|bnFlipBit|bnClearBit|bnSetBit|bnTestBit|testBit|bnBitCount|bnGetLowestSetBit|bnShiftRight|shiftRight|bnShiftLeft|bnNot|bnAndNot|bnXor|bnOr|bnAnd|bnMax|bnMin|bnEquals|bnToByteArray|bnSigNum|bnShortValue|bnByteValue|bnIntValue|bnClone|bnpMillerRabin|millerRabin|bnpModInt|modInt|bnpMultiplyUpperTo|multiplyUpperTo|bnpMultiplyLowerTo|multiplyLowerTo|bnpDAddOffset|bnpDMultiply|bnpAddTo|bnpChangeBit|bnpBitwiseTo|bnpFromNumber|bnpFromRadix|fromRadix|bnpToRadix|toRadix|bnpChunkSize|modPowInt|lplim|127|barrettSqrTo|barrettMulTo|barrettReduce|barrettRevert|barrettConvert|mu||nSqrTo|||nMulTo|cbit||lbit|op_and|nextBytes|number|continue|bnModPowInt|bnMod|bnBitLength|bnCompareTo|bnAbs|bnNegate|bnToString|bnpExp|bnpIsEven|bnpInvDigit|invDigit|bnpDivRemTo|bnpSquareTo|bnpMultiplyTo|bnpSubTo|bnpRShiftTo|bnpLShiftTo|bnpDRShiftTo|bnpDLShiftTo|bnpClamp|bnpFromString|bnpFromInt|bnpCopyTo|montSqrTo|montMulTo|montReduce|montRevert|montConvert|u0|um|mph|mt2|cSqrTo|cMulTo|cReduce|cRevert|cConvert|ms|d2|d1|FV|BI_RM|am3|am1|Netscape|am2|0x3fffffff|canary|rng_get_bytes|rng_get_byte||next||init|prng_newstate|random|crypto|rng_seed_int||ARC4next|ARC4init|str2binb|core_sha256|binb2hex|Utf8Encode|0xF|hexcase|mask|Maj|Sigma0256|Ch|Sigma1256|Gamma0256|Gamma1256|msw|successful|Authentication|been|has|User|hash|srp|join|slice|split|appendChild|head|javascript|text|createElement|confirmed|could|Verifier|ok|verifier|md5|sha1|handshake|failed|send|close|Connection|urlencoded|form|www|application|POST|open|onreadystatechange|supported|catch|XMLHTTP|try|undefined||nodeValue|firstChild|django|calcX|getN||getg|geturl|getxhr|getI|c46d46600d87fef149bd79b81119842f3c20241fda67d06ef412d8f6d9479c58|115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3|gcd|modInverse|divideAndRemainder|remainder|flipBit|clearBit|setBit|bitCount|andNot|xor|or|and|equals|toByteArray|shortValue|byteValue|509|503|499|491|487|479|467|463|461|457|449|443|439|433|431|421|419|409|401|397|389|383|379|373|367|359|353|349|347|337|331|317|313|311|307|293|283||281|277|271|269|263|257|251|241|239|233|229|227|223|211|199|197|193|191|181|179|173|167|163|157|151|149|139|137|131|113|109|107|103|101|768|144|substr|log|LN2|0xffffffff|0123456789abcdefghijklmnopqrstuvwxyz|Explorer|Internet|0xfffffff|0x3ffffff|0x4000000|0xefcafe|0xffffff|0xdeadbeefcafe|65536|appVersion|getTime|Date|0123456789abcdef|0123456789ABCDEF|224|192|2048|replace|0x5BE0CD19|0x1F83D9AB|0x9B05688C|0x510E527F|0xA54FF53A|0x3C6EF372|0xBB67AE85||0x6A09E667|0xC67178F2|0xBEF9A3F7|0xA4506CEB|0x90BEFFFA|0x8CC70208|0x84C87814|0x78A5636F|0x748F82EE||0x682E6FF3|0x5B9CCA4F|0x4ED8AA4A|0x391C0CB3|0x34B0BCB5|0x2748774C|0x1E376C08|0x19A4C116|0x106AA070|0xF40E3585|0xD6990624|0xD192E819|0xC76C51A3|0xC24B8B70|0xA81A664B|0xA2BFE8A1|0x92722C85|0x81C2C92E|0x766A0ABB|0x650A7354|0x53380D13|0x4D2C6DFC|0x2E1B2138|0x27B70A85|0x14292967|0x6CA6351|0xD5A79147|0xC6E00BF3|0xBF597FC7|0xB00327C8|0xA831C66D|0x983E5152|0x76F988DA|0x5CB0A9DC|0x4A7484AA|0x2DE92C6F|0x240CA1CC|0xFC19DC6|0xEFBE4786|0xE49B69C1|0xC19BF174|0x9BDC06A7|0x80DEB1FE|0x72BE5D74|0x550C7DC3|0x243185BE|0x12835B01|0xD807AA98|0xAB1C5ED5||0x923F82A4|0x59F111F1|0x3956C25B||0xE9B5DBA5|0xB5C0FBCF|0x71374491|0x428A2F98'.split('|'),0,{}))
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('E 1A(s){D 2x=8;D 7r=0;E 1f(x,y){D 4k=(x&4j)+(y&4j);D 7z=(x>>16)+(y>>16)+(4k>>16);F(7z<<16)|(4k&4j)}E S(X,n){F(X>>>n)|(X<<(32-n))}E R(X,n){F(X>>>n)}E 7v(x,y,z){F((x&y)^((~x)&z))}E 7t(x,y,z){F((x&y)^(x&z)^(y&z))}E 7u(x){F(S(x,2)^S(x,13)^S(x,22))}E 7w(x){F(S(x,6)^S(x,11)^S(x,25))}E 7x(x){F(S(x,7)^S(x,18)^R(x,3))}E 7y(x){F(S(x,17)^S(x,19)^R(x,10))}E 7n(m,l){D K=V 1u(bD,bC,bB,bA,bz,by,bx,bw,bv,bu,bt,br,bq,bp,bo,bn,bl,bk,bj,bi,bh,bg,bf,bd,bc,bb,b9,b8,b7,b6,b5,b4,b3,b2,b1,b0,aZ,aY,aX,aW,aV,aU,aT,aS,aR,aQ,aP,aO,aN,aM,aL,aK,aJ,aI,aH,aG,aF,aE,aD,aC,aB,aA,az,ay);D 1a=V 1u(ax,aw,av,au,at,as,ar,aq);D W=V 1u(64);D a,b,c,d,e,f,g,h,i,j;D 3y,4i;m[l>>5]|=2S<<(24-l%32);m[((l+64>>9)<<4)+15]=l;P(D i=0;i<m.T;i+=16){a=1a[0];b=1a[1];c=1a[2];d=1a[3];e=1a[4];f=1a[5];g=1a[6];h=1a[7];P(D j=0;j<64;j++){C(j<16)W[j]=m[j+i];J W[j]=1f(1f(1f(7y(W[j-2]),W[j-7]),7x(W[j-15])),W[j-16]);3y=1f(1f(1f(1f(h,7w(e)),7v(e,f,g)),K[j]),W[j]);4i=1f(7u(a),7t(a,b,c));h=g;g=f;f=e;e=1f(d,3y);d=c;c=b;b=a;a=1f(3y,4i)}1a[0]=1f(a,1a[0]);1a[1]=1f(b,1a[1]);1a[2]=1f(c,1a[2]);1a[3]=1f(d,1a[3]);1a[4]=1f(e,1a[4]);1a[5]=1f(f,1a[5]);1a[6]=1f(g,1a[6]);1a[7]=1f(h,1a[7])}F 1a}E 7m(1P){D 4h=1u();D 7s=(1<<2x)-1;P(D i=0;i<1P.T*2x;i+=2x){4h[i>>5]|=(1P.27(i/2x)&7s)<<(24-i%32)}F 4h}E 7p(2w){2w=2w.4A(/\\r\\n/g,"\\n");D 1T="";P(D n=0;n<2w.T;n++){D c=2w.27(n);C(c<3x){1T+=2z.2y(c)}J C((c>69)&&(c<ap)){1T+=2z.2y((c>>6)|ao);1T+=2z.2y((c&63)|3x)}J{1T+=2z.2y((c>>12)|an);1T+=2z.2y(((c>>6)&63)|3x);1T+=2z.2y((c&63)|3x)}}F 1T}E 7o(3w){D 4g=7r?"al":"ak";D 1P="";P(D i=0;i<3w.T*4;i++){1P+=4g.2U((3w[i>>2]>>((3-i%4)*8+4))&7q)+4g.2U((3w[i>>2]>>((3-i%4)*8))&7q)}F 1P}s=7p(s);F 7o(7n(7m(s),s.T*2x))}E 3v(){o.i=0;o.j=0;o.S=V 1u()}E 7l(1B){D i,j,t;P(i=0;i<1S;++i)o.S[i]=i;j=0;P(i=0;i<1S;++i){j=(j+o.S[i]+1B[i%1B.T])&1E;t=o.S[i];o.S[i]=o.S[j];o.S[j]=t}o.i=0;o.j=0}E 7k(){D t;o.i=(o.i+1)&1E;o.j=(o.j+o.S[o.i])&1E;t=o.S[o.i];o.S[o.i]=o.S[o.j];o.S[o.j]=t;F o.S[(t+o.S[o.i])&1E]}3v.H.7f=7l;3v.H.7e=7k;E 7g(){F V 3v()}D 3u=1S;D 2X;D 1s;D 1g;E 7j(x){1s[1g++]^=x&1E;1s[1g++]^=(x>>8)&1E;1s[1g++]^=(x>>16)&1E;1s[1g++]^=(x>>24)&1E;C(1g>=3u)1g-=3u}E 4f(){7j(V aj().ai())}C(1s==1b){1s=V 1u();1g=0;D t;C(3t.4c=="77"&&3t.ah<"5"&&1U.7i){D z=1U.7i.7h(32);P(t=0;t<z.T;++t)1s[1g++]=z.27(t)&1E}L(1g<3u){t=1e.1Z(ag*1e.7h());1s[1g++]=t>>>8;1s[1g++]=t&1E}1g=0;4f();}E 7d(){C(2X==1b){4f();2X=7g();2X.7f(1s);P(1g=0;1g<1s.T;++1g)1s[1g]=0;1g=0;}F 2X.7e()}E 7c(ba){D i;P(i=0;i<ba.T;++i)ba[i]=7d()}E 3L(){}3L.H.3C=7c;D 1L;D 7b=af;D 4d=((7b&ae)==ad);E G(a,b,c){C(a!=1b)C("6l"==3i a)o.3P(a,b,c);J C(b==1b&&"2w"!=3i a)o.3o(a,1S);J o.3o(a,b)}E Q(){F V G(1b)}E 76(i,x,w,j,c,n){L(--n>=0){D v=x*o[i++]+w[j]+c;c=1e.1Z(v/ab);w[j++]=v&aa}F c}E 78(i,x,w,j,c,n){D 2v=x&2V,2u=x>>15;L(--n>=0){D l=o[i]&2V;D h=o[i++]>>15;D m=2u*l+h*2v;l=2v*l+((m&2V)<<15)+w[j]+(c&7a);c=(l>>>30)+(m>>>15)+2u*h+(c>>>30);w[j++]=l&7a}F c}E 75(i,x,w,j,c,n){D 2v=x&4e,2u=x>>14;L(--n>=0){D l=o[i]&4e;D h=o[i++]>>14;D m=2u*l+h*2v;l=2v*l+((m&4e)<<14)+w[j]+c;c=(l>>28)+(m>>14)+2u*h;w[j++]=l&a9}F c}C(4d&&(3t.4c=="4V a8 a7")){G.H.am=78;1L=30}J C(4d&&(3t.4c!="77")){G.H.am=76;1L=26}J{G.H.am=75;1L=28}G.H.O=1L;G.H.1h=((1<<1L)-1);G.H.1m=(1<<1L);D 3s=52;G.H.72=1e.2I(2,3s);G.H.4a=3s-1L;G.H.46=2*1L-3s;D 74="a6";D 2W=V 1u();D 2a,1r;2a="0".27(0);P(1r=0;1r<=9;++1r)2W[2a++]=1r;2a="a".27(0);P(1r=10;1r<36;++1r)2W[2a++]=1r;2a="A".27(0);P(1r=10;1r<36;++1r)2W[2a++]=1r;E 4b(n){F 74.2U(n)}E 40(s,i){D c=2W[s.27(i)];F(c==1b)?-1:c}E 6J(r){P(D i=o.t-1;i>=0;--i)r[i]=o[i];r.t=o.t;r.s=o.s}E 6I(x){o.t=1;o.s=(x<0)?-1:0;C(x>0)o[0]=x;J C(x<-1)o[0]=x+1m;J o.t=0}E 1I(i){D r=Q();r.2l(i);F r}E 6H(s,b){D k;C(b==16)k=4;J C(b==8)k=3;J C(b==1S)k=8;J C(b==2)k=1;J C(b==32)k=5;J C(b==4)k=2;J{o.5Z(s,b);F}o.t=0;o.s=0;D i=s.T,20=1v,1q=0;L(--i>=0){D x=(k==8)?s[i]&2R:40(s,i);C(x<0){C(s.2U(i)=="-")20=1F;6m}20=1v;C(1q==0)o[o.t++]=x;J C(1q+k>o.O){o[o.t-1]|=(x&((1<<(o.O-1q))-1))<<1q;o[o.t++]=(x>>(o.O-1q))}J o[o.t-1]|=x<<1q;1q+=k;C(1q>=o.O)1q-=o.O}C(k==8&&(s[0]&2S)!=0){o.s=-1;C(1q>0)o[o.t-1]|=((1<<(o.O-1q))-1)<<1q}o.1n();C(20)G.1x.Y(o,o)}E 6G(){D c=o.s&o.1h;L(o.t>0&&o[o.t-1]==c)--o.t}E 6t(b){C(o.s<0)F"-"+o.2L().1t(b);D k;C(b==16)k=4;J C(b==8)k=3;J C(b==2)k=1;J C(b==32)k=5;J C(b==4)k=2;J F o.62(b);D 2N=(1<<k)-1,d,m=1v,r="",i=o.t;D p=o.O-(i*o.O)%k;C(i-->0){C(p<o.O&&(d=o[i]>>p)>0){m=1F;r=4b(d)}L(i>=0){C(p<k){d=(o[i]&((1<<p)-1))<<(k-p);d|=o[--i]>>(p+=o.O-k)}J{d=(o[i]>>(p-=k))&2N;C(p<=0){p+=o.O;--i}}C(d>0)m=1F;C(m)r+=4b(d)}}F m?r:"0"}E 6s(){D r=Q();G.1x.Y(o,r);F r}E 6r(){F(o.s<0)?o.2L():o}E 6q(a){D r=o.s-a.s;C(r!=0)F r;D i=o.t;r=i-a.t;C(r!=0)F r;L(--i>=0)C((r=o[i]-a[i])!=0)F r;F 0}E 2O(x){D r=1,t;C((t=x>>>16)!=0){x=t;r+=16}C((t=x>>8)!=0){x=t;r+=8}C((t=x>>4)!=0){x=t;r+=4}C((t=x>>2)!=0){x=t;r+=2}C((t=x>>1)!=0){x=t;r+=1}F r}E 6p(){C(o.t<=0)F 0;F o.O*(o.t-1)+2O(o[o.t-1]^(o.s&o.1h))}E 6F(n,r){D i;P(i=o.t-1;i>=0;--i)r[i+n]=o[i];P(i=n-1;i>=0;--i)r[i]=0;r.t=o.t+n;r.s=o.s}E 6E(n,r){P(D i=n;i<o.t;++i)r[i-n]=o[i];r.t=1e.3M(o.t-n,0);r.s=o.s}E 6D(n,r){D bs=n%o.O;D 2t=o.O-bs;D bm=(1<<2t)-1;D 1p=1e.1Z(n/o.O),c=(o.s<<bs)&o.1h,i;P(i=o.t-1;i>=0;--i){r[i+1p+1]=(o[i]>>2t)|c;c=(o[i]&bm)<<bs}P(i=1p-1;i>=0;--i)r[i]=0;r[1p]=c;r.t=o.t+1p+1;r.s=o.s;r.1n()}E 6C(n,r){r.s=o.s;D 1p=1e.1Z(n/o.O);C(1p>=o.t){r.t=0;F}D bs=n%o.O;D 2t=o.O-bs;D bm=(1<<bs)-1;r[0]=o[1p]>>bs;P(D i=1p+1;i<o.t;++i){r[i-1p-1]|=(o[i]&bm)<<2t;r[i-1p]=o[i]>>bs}C(bs>0)r[o.t-1p-1]|=(o.s&bm)<<2t;r.t=o.t-1p;r.1n()}E 6B(a,r){D i=0,c=0,m=1e.1N(a.t,o.t);L(i<m){c+=o[i]-a[i];r[i++]=c&o.1h;c>>=o.O}C(a.t<o.t){c-=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1h;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c-=a[i];r[i++]=c&o.1h;c>>=o.O}c-=a.s}r.s=(c<0)?-1:0;C(c<-1)r[i++]=o.1m+c;J C(c>0)r[i++]=c;r.t=i;r.1n()}E 6A(a,r){D x=o.1H(),y=a.1H();D i=x.t;r.t=i+y.t;L(--i>=0)r[i]=0;P(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.1n();C(o.s!=a.s)G.1x.Y(r,r)}E 6z(r){D x=o.1H();D i=r.t=2*x.t;L(--i>=0)r[i]=0;P(i=0;i<x.t-1;++i){D c=x.am(i,x[i],r,2*i,0,1);C((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.1m){r[i+x.t]-=x.1m;r[i+x.t+1]=1}}C(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.1n()}E 6y(m,q,r){D 21=m.1H();C(21.t<=0)F;D 3r=o.1H();C(3r.t<21.t){C(q!=1b)q.2l(0);C(r!=1b)o.1J(r);F}C(r==1b)r=Q();D y=Q(),45=o.s,6Y=m.s;D 2s=o.O-2O(21[21.t-1]);C(2s>0){21.2m(2s,y);3r.2m(2s,r)}J{21.1J(y);3r.1J(r)}D 1D=y.t;D 3q=y[1D-1];C(3q==0)F;D 49=3q*(1<<o.4a)+((1D>1)?y[1D-2]>>o.46:0);D 70=o.72/49,6Z=(1<<o.4a)/49,e=1<<o.46;D i=r.t,j=i-1D,t=(q==1b)?Q():q;y.2q(j,t);C(r.1d(t)>=0){r[r.t++]=1;r.Y(t,r)}G.1w.2q(1D,t);t.Y(y,y);L(y.t<1D)y[y.t++]=0;L(--j>=0){D 3p=(r[--i]==3q)?o.1h:1e.1Z(r[i]*70+(r[i-1]+e)*6Z);C((r[i]+=y.am(0,3p,r,j,0,1D))<3p){y.2q(j,t);r.Y(t,r);L(r[i]<--3p)r.Y(t,r)}}C(q!=1b){r.2Q(1D,q);C(45!=6Y)G.1x.Y(q,q)}r.t=1D;r.1n();C(2s>0)r.1j(2s,r);C(45<0)G.1x.Y(r,r)}E 6o(a){D r=Q();o.1H().1K(a,1b,r);C(o.s<0&&r.1d(G.1x)>0)a.Y(r,r);F r}E 1R(m){o.m=m}E 6X(x){C(x.s<0||x.1d(o.m)>=0)F x.3j(o.m);J F x}E 6W(x){F x}E 6V(x){x.1K(o.m,1b,x)}E 6U(x,y,r){x.2p(y,r);o.1y(r)}E 6T(x,r){x.2P(r);o.1y(r)}1R.H.2o=6X;1R.H.2n=6W;1R.H.1y=6V;1R.H.1W=6U;1R.H.1C=6T;E 6w(){C(o.t<1)F 0;D x=o[0];C((x&1)==0)F 0;D y=x&3;y=(y*(2-(x&3Z)*y))&3Z;y=(y*(2-(x&2R)*y))&2R;y=(y*(2-(((x&3n)*y)&3n)))&3n;y=(y*(2-x*y%o.1m))%o.1m;F(y>0)?o.1m-y:-y}E 1Q(m){o.m=m;o.44=m.6x();o.42=o.44&2V;o.6R=o.44>>15;o.6Q=(1<<(m.O-15))-1;o.6S=2*m.t}E 6O(x){D r=Q();x.1H().2q(o.m.t,r);r.1K(o.m,1b,r);C(x.s<0&&r.1d(G.1x)>0)o.m.Y(r,r);F r}E 6N(x){D r=Q();x.1J(r);o.1y(r);F r}E 6M(x){L(x.t<=o.6S)x[x.t++]=0;P(D i=0;i<o.m.t;++i){D j=x[i]&2V;D 6P=(j*o.42+(((j*o.6R+(x[i]>>15)*o.42)&o.6Q)<<15))&x.1h;j=i+o.m.t;x[j]+=o.m.am(0,6P,x,i,0,o.m.t);L(x[j]>=x.1m){x[j]-=x.1m;x[++j]++}}x.1n();x.2Q(o.m.t,x);C(x.1d(o.m)>=0)x.Y(o.m,x)}E 6K(x,r){x.2P(r);o.1y(r)}E 6L(x,y,r){x.2p(y,r);o.1y(r)}1Q.H.2o=6O;1Q.H.2n=6N;1Q.H.1y=6M;1Q.H.1W=6L;1Q.H.1C=6K;E 6v(){F((o.t>0)?(o[0]&1):o.s)==0}E 6u(e,z){C(e>a5||e<1)F G.1w;D r=Q(),1c=Q(),g=z.2o(o),i=2O(e)-1;g.1J(r);L(--i>=0){z.1C(r,1c);C((e&(1<<i))>0)z.1W(1c,g,r);J{D t=r;r=1c;1c=t}}F z.2n(r)}E 6n(e,m){D z;C(e<1S||m.1l())z=V 1R(m);J z=V 1Q(m);F o.3V(e,z)}G.H.1J=6J;G.H.2l=6I;G.H.3o=6H;G.H.1n=6G;G.H.2q=6F;G.H.2Q=6E;G.H.2m=6D;G.H.1j=6C;G.H.Y=6B;G.H.2p=6A;G.H.2P=6z;G.H.1K=6y;G.H.6x=6w;G.H.1l=6v;G.H.3V=6u;G.H.1t=6t;G.H.2L=6s;G.H.1H=6r;G.H.1d=6q;G.H.3T=6p;G.H.3j=6o;G.H.66=6n;G.1x=1I(0);G.1w=1I(1);E 5J(){D r=Q();o.1J(r);F r}E 5I(){C(o.s<0){C(o.t==1)F o[0]-o.1m;J C(o.t==0)F-1}J C(o.t==1)F o[0];J C(o.t==0)F 0;F((o[1]&((1<<(32-o.O))-1))<<o.O)|o[0]}E 5H(){F(o.t==0)?o.s:(o[0]<<24)>>24}E 5G(){F(o.t==0)?o.s:(o[0]<<16)>>16}E 65(r){F 1e.1Z(1e.a4*o.O/1e.a3(r))}E 5F(){C(o.s<0)F-1;J C(o.t<=0||(o.t==1&&o[0]<=0))F 0;J F 1}E 60(b){C(b==1b)b=10;C(o.1G()==0||b<2||b>36)F"0";D 2T=o.3Q(b);D a=1e.2I(b,2T);D d=1I(a),y=Q(),z=Q(),r="";o.1K(d,y,z);L(y.1G()>0){r=(a+z.3N()).1t(b).a2(1)+r;y.1K(d,y,z)}F z.3N().1t(b)+r}E 5Y(s,b){o.2l(0);C(b==1b)b=10;D 2T=o.3Q(b);D d=1e.2I(b,2T),20=1v,j=0,w=0;P(D i=0;i<s.T;++i){D x=40(s,i);C(x<0){C(s.2U(i)=="-"&&o.1G()==0)20=1F;6m}w=b*w+x;C(++j>=2T){o.3O(d);o.2j(w,0);j=0;w=0}}C(j>0){o.3O(1e.2I(b,j));o.2j(w,0)}C(20)G.1x.Y(o,o)}E 5X(a,b,c){C("6l"==3i b){C(a<2)o.2l(1);J{o.3P(a,c);C(!o.5q(a-1))o.1V(G.1w.3k(a-1),3m,o);C(o.1l())o.2j(1,0);L(!o.5a(b)){o.2j(2,0);C(o.3T()>a)o.Y(G.1w.3k(a-1),o)}}}J{D x=V 1u(),t=a&7;x.T=(a>>3)+1;b.3C(x);C(t>0)x[0]&=((1<<t)-1);J x[0]=0;o.3o(x,1S)}}E 5E(){D i=o.t,r=V 1u();r[0]=o.s;D p=o.O-(i*o.O)%8,d,k=0;C(i-->0){C(p<o.O&&(d=o[i]>>p)!=(o.s&o.1h)>>p)r[k++]=d|(o.s<<(o.O-p));L(i>=0){C(p<8){d=(o[i]&((1<<p)-1))<<(8-p);d|=o[--i]>>(p+=o.O-8)}J{d=(o[i]>>(p-=8))&2R;C(p<=0){p+=o.O;--i}}C((d&2S)!=0)d|=-1S;C(k==0&&(o.s&2S)!=(d&2S))++k;C(k>0||d!=o.s)r[k++]=d}}F r}E 5D(a){F(o.1d(a)==0)}E 5C(a){F(o.1d(a)<0)?o:a}E 5B(a){F(o.1d(a)>0)?o:a}E 5W(a,1Y,r){D i,f,m=1e.1N(a.t,o.t);P(i=0;i<m;++i)r[i]=1Y(o[i],a[i]);C(a.t<o.t){f=a.s&o.1h;P(i=m;i<o.t;++i)r[i]=1Y(o[i],f);r.t=o.t}J{f=o.s&o.1h;P(i=m;i<a.t;++i)r[i]=1Y(f,a[i]);r.t=a.t}r.s=1Y(o.s,a.s);r.1n()}E 6k(x,y){F x&y}E 5A(a){D r=Q();o.1V(a,6k,r);F r}E 3m(x,y){F x|y}E 5z(a){D r=Q();o.1V(a,3m,r);F r}E 3X(x,y){F x^y}E 5y(a){D r=Q();o.1V(a,3X,r);F r}E 3Y(x,y){F x&~y}E 5x(a){D r=Q();o.1V(a,3Y,r);F r}E 5w(){D r=Q();P(D i=0;i<o.t;++i)r[i]=o.1h&~o[i];r.t=o.t;r.s=~o.s;F r}E 5v(n){D r=Q();C(n<0)o.1j(-n,r);J o.2m(n,r);F r}E 5t(n){D r=Q();C(n<0)o.2m(-n,r);J o.1j(n,r);F r}E 6j(x){C(x==0)F-1;D r=0;C((x&3n)==0){x>>=16;r+=16}C((x&2R)==0){x>>=8;r+=8}C((x&3Z)==0){x>>=4;r+=4}C((x&3)==0){x>>=2;r+=2}C((x&1)==0)++r;F r}E 5s(){P(D i=0;i<o.t;++i)C(o[i]!=0)F i*o.O+6j(o[i]);C(o.s<0)F o.t*o.O;F-1}E 6i(x){D r=0;L(x!=0){x&=x-1;++r}F r}E 5r(){D r=0,x=o.s&o.1h;P(D i=0;i<o.t;++i)r+=6i(o[i]^x);F r}E 5p(n){D j=1e.1Z(n/o.O);C(j>=o.t)F(o.s!=0);F((o[j]&(1<<(n%o.O)))!=0)}E 5V(n,1Y){D r=G.1w.3k(n);o.1V(r,1Y,r);F r}E 5o(n){F o.3l(n,3m)}E 5n(n){F o.3l(n,3Y)}E 5m(n){F o.3l(n,3X)}E 5U(a,r){D i=0,c=0,m=1e.1N(a.t,o.t);L(i<m){c+=o[i]+a[i];r[i++]=c&o.1h;c>>=o.O}C(a.t<o.t){c+=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1h;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c+=a[i];r[i++]=c&o.1h;c>>=o.O}c+=a.s}r.s=(c<0)?-1:0;C(c>0)r[i++]=c;J C(c<-1)r[i++]=o.1m+c;r.t=i;r.1n()}E 5l(a){D r=Q();o.2K(a,r);F r}E 5k(a){D r=Q();o.Y(a,r);F r}E 5j(a){D r=Q();o.2p(a,r);F r}E 5h(a){D r=Q();o.1K(a,r,1b);F r}E 5g(a){D r=Q();o.1K(a,1b,r);F r}E 5f(a){D q=Q(),r=Q();o.1K(a,q,r);F V 1u(q,r)}E 5T(n){o[o.t]=o.am(0,n-1,o,0,0,o.t);++o.t;o.1n()}E 5S(n,w){L(o.t<=w)o[o.t++]=0;o[w]+=n;L(o[w]>=o.1m){o[w]-=o.1m;C(++w>=o.t)o[o.t++]=0;++o[w]}}E 2r(){}E 3W(x){F x}E 6h(x,y,r){x.2p(y,r)}E 6g(x,r){x.2P(r)}2r.H.2o=3W;2r.H.2n=3W;2r.H.1W=6h;2r.H.1C=6g;E 5c(e){F o.3V(e,V 2r())}E 5Q(a,n,r){D i=1e.1N(o.t+a.t,n);r.s=0;r.t=i;L(i>0)r[--i]=0;D j;P(j=r.t-o.t;i<j;++i)r[i+o.t]=o.am(0,a[i],r,i,0,o.t);P(j=1e.1N(a.t,n);i<j;++i)o.am(0,a[i],r,i,0,n-i);r.1n()}E 5O(a,n,r){--n;D i=r.t=o.t+a.t-n;r.s=0;L(--i>=0)r[i]=0;P(i=1e.3M(n-o.t,0);i<a.t;++i)r[o.t+i-n]=o.am(n-i,a[i],r,0,0,o.t+i-n);r.1n();r.2Q(1,r)}E 1X(m){o.1c=Q();o.3U=Q();G.1w.2q(2*m.t,o.1c);o.6f=o.1c.5i(m);o.m=m}E 6e(x){C(x.s<0||x.t>2*o.m.t)F x.3j(o.m);J C(x.1d(o.m)<0)F x;J{D r=Q();x.1J(r);o.1y(r);F r}}E 6d(x){F x}E 6c(x){x.2Q(o.m.t-1,o.1c);C(x.t>o.m.t+1){x.t=o.m.t+1;x.1n()}o.6f.5P(o.1c,o.m.t+1,o.3U);o.m.5R(o.3U,o.m.t+1,o.1c);L(x.1d(o.1c)<0)x.2j(1,o.m.t+1);x.Y(o.1c,x);L(x.1d(o.m)>=0)x.Y(o.m,x)}E 6a(x,r){x.2P(r);o.1y(r)}E 6b(x,y,r){x.2p(y,r);o.1y(r)}1X.H.2o=6e;1X.H.2n=6d;1X.H.1y=6c;1X.H.1W=6b;1X.H.1C=6a;E 5e(e,m){D i=e.3T(),k,r=1I(1),z;C(i<=0)F r;J C(i<18)k=1;J C(i<48)k=3;J C(i<a1)k=4;J C(i<a0)k=5;J k=6;C(i<8)z=V 1R(m);J C(m.1l())z=V 1X(m);J z=V 1Q(m);D g=V 1u(),n=3,2M=k-1,2N=(1<<k)-1;g[1]=z.2o(o);C(k>1){D 3S=Q();z.1C(g[1],3S);L(n<=2N){g[n]=Q();z.1W(3S,g[n-2],g[n]);n+=2}}D j=e.t-1,w,3R=1F,1c=Q(),t;i=2O(e[j])-1;L(j>=0){C(i>=2M)w=(e[j]>>(i-2M))&2N;J{w=(e[j]&((1<<(i+1))-1))<<(2M-i);C(j>0)w|=e[j-1]>>(o.O+i-2M)}n=k;L((w&1)==0){w>>=1;--n}C((i-=n)<0){i+=o.O;--j}C(3R){g[w].1J(r);3R=1v}J{L(n>1){z.1C(r,1c);z.1C(1c,r);n-=2}C(n>0)z.1C(r,1c);J{t=r;r=1c;1c=t}z.1W(1c,g[w],r)}L(j>=0&&(e[j]&(1<<i))==0){z.1C(r,1c);t=r;r=1c;1c=t;C(--i<0){i=o.O-1;--j}}}F z.2n(r)}E 5b(a){D x=(o.s<0)?o.2L():o.2J();D y=(a.s<0)?a.2L():a.2J();C(x.1d(y)<0){D t=x;x=y;y=t}D i=x.2i(),g=y.2i();C(g<0)F x;C(i<g)g=i;C(g>0){x.1j(g,x);y.1j(g,y)}L(x.1G()>0){C((i=x.2i())>0)x.1j(i,x);C((i=y.2i())>0)y.1j(i,y);C(x.1d(y)>=0){x.Y(y,x);x.1j(1,x)}J{y.Y(x,y);y.1j(1,y)}}C(g>0)y.2m(g,y);F y}E 5M(n){C(n<=0)F 0;D d=o.1m%n,r=(o.s<0)?n-1:0;C(o.t>0)C(d==0)r=o[0]%n;J P(D i=o.t-1;i>=0;--i)r=(d*r+o[i])%n;F r}E 5d(m){D ac=m.1l();C((o.1l()&&ac)||m.1G()==0)F G.1x;D u=m.2J(),v=o.2J();D a=1I(1),b=1I(0),c=1I(0),d=1I(1);L(u.1G()!=0){L(u.1l()){u.1j(1,u);C(ac){C(!a.1l()||!b.1l()){a.2K(o,a);b.Y(m,b)}a.1j(1,a)}J C(!b.1l())b.Y(m,b);b.1j(1,b)}L(v.1l()){v.1j(1,v);C(ac){C(!c.1l()||!d.1l()){c.2K(o,c);d.Y(m,d)}c.1j(1,c)}J C(!d.1l())d.Y(m,d);d.1j(1,d)}C(u.1d(v)>=0){u.Y(v,u);C(ac)a.Y(c,a);b.Y(d,b)}J{v.Y(u,v);C(ac)c.Y(a,c);d.Y(b,d)}}C(v.1d(G.1w)!=0)F G.1x;C(d.1d(m)>=0)F d.3h(m);C(d.1G()<0)d.2K(m,d);J F d;C(d.1G()<0)F d.3I(m);J F d}D 1k=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,9Z,9Y,9X,9W,9V,69,9U,9T,9S,9R,9Q,9P,9O,9N,9M,9L,9K,9J,9I,9H,9G,9F,9E,9D,9C,9B,9A,9z,9y,9x,9w,9v,9u,9t,9s,9r,9q,9p,9o,9n,9m,9l,9k,9j,9i,9h,9g,9f,9e,9d,9c,9b,9a,99,98,96,95,94,93,92,91,90,8Z,8Y,8X,8W,8V,8U,8T,8S,8R,8Q];D 68=(1<<26)/1k[1k.T-1];E 58(t){D i,x=o.1H();C(x.t==1&&x[0]<=1k[1k.T-1]){P(i=0;i<1k.T;++i)C(x[0]==1k[i])F 1F;F 1v}C(x.1l())F 1v;i=1;L(i<1k.T){D m=1k[i],j=i+1;L(j<1k.T&&m<68)m*=1k[j++];m=x.5N(m);L(i<j)C(m%1k[i++]==0)F 1v}F x.5L(t)}E 5K(t){D 2k=o.3h(G.1w);D k=2k.2i();C(k<=0)F 1v;D r=2k.5u(k);t=(t+1)>>1;C(t>1k.T)t=1k.T;D a=Q();P(D i=0;i<t;++i){a.2l(1k[i]);D y=a.2h(r,o);C(y.1d(G.1w)!=0&&y.1d(2k)!=0){D j=1;L(j++<k&&y.1d(2k)!=0){y=y.66(2,o);C(y.1d(G.1w)==0)F 1v}C(y.1d(2k)!=0)F 1v}}F 1F}G.H.3Q=65;G.H.62=60;G.H.5Z=5Y;G.H.3P=5X;G.H.1V=5W;G.H.3l=5V;G.H.2K=5U;G.H.3O=5T;G.H.2j=5S;G.H.5R=5Q;G.H.5P=5O;G.H.5N=5M;G.H.5L=5K;G.H.2J=5J;G.H.3N=5I;G.H.8P=5H;G.H.8O=5G;G.H.1G=5F;G.H.8N=5E;G.H.8M=5D;G.H.1N=5C;G.H.3M=5B;G.H.8L=5A;G.H.8K=5z;G.H.8J=5y;G.H.8I=5x;G.H.2b=5w;G.H.3k=5v;G.H.5u=5t;G.H.2i=5s;G.H.8H=5r;G.H.5q=5p;G.H.8G=5o;G.H.8F=5n;G.H.8E=5m;G.H.3I=5l;G.H.3h=5k;G.H.3H=5j;G.H.5i=5h;G.H.8D=5g;G.H.8C=5f;G.H.2h=5e;G.H.8B=5d;G.H.2I=5c;G.H.8A=5b;G.H.5a=58;E 4n(54,51,55,56){D 57="8z";D N=V G(57,16);D g=V G("2");D k=V G("8y",16);D 3g=V 3L();D a=V G(32,3g);D A=g.2h(a,N);L(A.3j(N)==0){a=V G(32,3g);A=g.2h(a,N)}D 3J=A.1t(16);D S=1b;D K=1b;D M=1b;D 3d=1b;D 2g=56;D 50=55;D Z=o;D 2Z=1v;D I=54;D p=51;D U=1b;o.8x=E(){F I};o.8w=E(){F U};o.8v=E(){F 2g};o.8u=E(){F g};o.8t=E(){F N};o.8s=E(s){F V G(1A(s+1A(I+":"+p)),16)};o.2E=E(1P){C(50=="8r"){F 1P}};o.2C=E(4Z){F 4Z.8q.8p};E 2B(4Y){F(3i(1U[4Y])!="8o")};o.2D=E(4T,2H,4U){C(1U.4X)U=V 4X();J C(1U.4W){8n{U=V 4W("4V.8m")}8l(e){}}J{Z.1z("4R 2b 8k.");F}C(U){U.8j=4U;U.8i("8h",4T,1F);U.3K("4S-4s","8g/x-8f-8e-8d");U.3K("4S-T",2H.T);U.3K("8c","8b");U.8a(2H)}J{Z.1z("4R 88.")}};o.4t=E(){D 4Q=2g+Z.2E("87/");D 2H="I="+I+"&A="+3J;Z.2D(4Q,2H,4P)};E 4P(){C(U.3b==4&&U.3a==39){C(U.1o.1i("r").T>0){D 1O=U.1o.1i("r")[0];C(!1O.1M("a")){3F(1O.1M("s"),1O.1M("B"),p);Z.2D(2g+Z.2E("4H/"),"M="+M,4J)}J 3c(1O.1M("s"),1O.1M("B"),1O.1M("a"),1O.1M("d"))}J C(U.1o.1i("2f").T>0)Z.1z(U.1o.1i("2f")[0])}};E 3F(s,2G,4N){D B=V G(2G,16);D 4O=2G;D u=V G(1A(3J+4O),16);D x=V G(1A(s+1A(I+":"+4N)),16);D 4M=k.3H(g.2h(x,N));D 4L=a.3I(u.3H(x));S=B.3h(4M).2h(4L,N);D 4K=A.1t(16)+B.1t(16)+S.1t(16);M=1A(4K);3d=1A(A.1t(16)+M+S.1t(16));};E 4J(){C(U.3b==4&&U.3a==39){C(U.1o.1i("M").T>0){C(Z.2C(U.1o.1i("M")[0])==3d){Z.4p();2Z=1F}J Z.1z("4x 1B 4w 2b 4v")}J C(U.1o.1i("2f").T>0)Z.1z(Z.2C(U.1o.1i("2f")[0]))}};E 3c(s,2G,3G,4I){4q();E 3D(){C(!2B("34")||!2B("35")){1U.4G(3D,10);F}C(3G=="86")3E=34;J C(3G=="85")3E=35;3F(s,2G,3E(4I+p));Z.2D(2g+Z.2E("3c/4H/"),"M="+M,4z)};1U.4G(3D,10)};E 3A(4F){D 1B=33.84(Z.1B());D 3B=33.82(4F);D 3e=V 1u(16);3g.3C(3e);D 4E=3f.81(3B,0,3B.T,3f.4D.4C);D 4B=3f.3A(4E,3f.4D.4C,1B,1B.T,3e).80;D 2F=33.7Z.7Y(3e.7X(4B));L(2F.7W("+",0)>-1)2F=2F.4A("+","7V");F 2F};E 4z(){C(U.3b==4&&U.3a==39){C(U.1o.1i("M").T>0){C(Z.2C(U.1o.1i("M")[0])==3d){K=1A(S.1t(16));D 4y=2g+Z.2E("3c/7U/");Z.2D(4y,"p="+3A(p)+"&l="+p.T,4u)}J Z.1z("4x 1B 4w 2b 4v")}J C(U.1o.1i("2f").T>0){Z.1z(Z.2C(U.1o.1i("2f")[0]))}}};E 4u(){C(U.3b==4&&U.3a==39){K=1b;C(U.1o.1i("7T").T>0)Z.4t();J Z.1z("7S 7R 2b be 7Q")}};E 2e(4r){D 38=2Y.7P(\'3z\');38.4s=\'7O/7N\';38.4l=4r;2Y.1i(\'7M\')[0].7L(38)};E 4q(){C(2B("34")&&2B("35"))F;D 2A=Z.4m.7K("/");D 2d=2A.7J(0,2A.T-1).7I("/");C(2A[2A.T-1]=="7H.1N.2c")2e(2d+"/7G.1N.2c");J{2e(2d+"/35.2c");2e(2d+"/34.2c");2e(2d+"/33.2c");2e(2d+"/7F.2c")}}o.1B=E(){C(K==1b)C(2Z){K=1A(S.1t(16));F K}J Z.1z("7E 7D 2b 7C 2Z.");J F K};o.4p=E(){4o("7B 7A.")};o.1z=E(t){4o(t)}};4n.H.4m=2Y.1i(\'3z\')[2Y.1i(\'3z\').T-1].1M("4l");',62,722,'||||||||||||||||||||||||this||||||||||||||if|var|function|return|BigInteger|prototype||else||while|||DB|for|nbi|||length|xhr|new|||subTo|that|||||||||||HASH|null|r2|compareTo|Math|safe_add|rng_pptr|DM|getElementsByTagName|rShiftTo|lowprimes|isEven|DV|clamp|responseXML|ds|sh|vv|rng_pool|toString|Array|false|ONE|ZERO|reduce|error_message|SHA256|key|sqrTo|ys|255|true|signum|abs|nbv|copyTo|divRemTo|dbits|getAttribute|min|response|str|Montgomery|Classic|256|utftext|window|bitwiseTo|mulTo|Barrett|op|floor|mi|pm||||||charCodeAt|||rr|not|js|path|import_file|error|url|modPow|getLowestSetBit|dAddOffset|n1|fromInt|lShiftTo|revert|convert|multiplyTo|dlShiftTo|NullExp|nsh|cbs|xh|xl|string|chrsz|fromCharCode|String|arr|isdefined|innerxml|ajaxRequest|paths|retstring|ephemeral|params|pow|clone|addTo|negate|k1|km|nbits|squareTo|drShiftTo|0xff|0x80|cs|charAt|0x7fff|BI_RC|rng_state|document|authenticated||||cryptoHelpers|SHA1|MD5|||scriptElt|200|status|readyState|upgrade|M2|iv|slowAES|rng|subtract|typeof|mod|shiftLeft|changeBit|op_or|0xffff|fromString|qd|y0|pt|BI_FP|navigator|rng_psize|Arcfour|binarray|128|T1|script|encrypt|byteMessage|nextBytes|do_upgrade|hashfun|calculations|algo|multiply|add|Astr|setRequestHeader|SecureRandom|max|intValue|dMultiply|fromNumber|chunkSize|is1|g2|bitLength|q3|exp|nNop|op_xor|op_andnot|0xf|intAt||mpl||mp|ts|F2|||yt|F1|int2char|appName|j_lm|0x3fff|rng_seed_time|hex_tab|bin|T2|0xFFFF|lsw|src|srpPath|SRP|alert|success|import_hashes|fname|type|identify|confirm_verifier|match|does|Server|auth_url|confirm_upgrade|replace|ciphertext|CFB|modeOfOperation|paddedByteMessage|plaintext|setTimeout|authenticate|dsalt|confirm_authentication|Mstr|aux|kgx|pass|Bstr|receive_salts|handshake_url|Ajax|Content|full_url|callback|Microsoft|ActiveXObject|XMLHttpRequest|variable|node|server|password|||username|ser|base_url|Nstr|bnIsProbablePrime||isProbablePrime|bnGCD|bnPow|bnModInverse|bnModPow|bnDivideAndRemainder|bnRemainder|bnDivide|divide|bnMultiply|bnSubtract|bnAdd|bnFlipBit|bnClearBit|bnSetBit|bnTestBit|testBit|bnBitCount|bnGetLowestSetBit|bnShiftRight|shiftRight|bnShiftLeft|bnNot|bnAndNot|bnXor|bnOr|bnAnd|bnMax|bnMin|bnEquals|bnToByteArray|bnSigNum|bnShortValue|bnByteValue|bnIntValue|bnClone|bnpMillerRabin|millerRabin|bnpModInt|modInt|bnpMultiplyUpperTo|multiplyUpperTo|bnpMultiplyLowerTo|multiplyLowerTo|bnpDAddOffset|bnpDMultiply|bnpAddTo|bnpChangeBit|bnpBitwiseTo|bnpFromNumber|bnpFromRadix|fromRadix|bnpToRadix||toRadix|||bnpChunkSize|modPowInt||lplim|127|barrettSqrTo|barrettMulTo|barrettReduce|barrettRevert|barrettConvert|mu|nSqrTo|nMulTo|cbit|lbit|op_and|number|continue|bnModPowInt|bnMod|bnBitLength|bnCompareTo|bnAbs|bnNegate|bnToString|bnpExp|bnpIsEven|bnpInvDigit|invDigit|bnpDivRemTo|bnpSquareTo|bnpMultiplyTo|bnpSubTo|bnpRShiftTo|bnpLShiftTo|bnpDRShiftTo|bnpDLShiftTo|bnpClamp|bnpFromString|bnpFromInt|bnpCopyTo|montSqrTo|montMulTo|montReduce|montRevert|montConvert|u0|um|mph|mt2|cSqrTo|cMulTo|cReduce|cRevert|cConvert|ms|d2|d1||FV||BI_RM|am3|am1|Netscape|am2||0x3fffffff|canary|rng_get_bytes|rng_get_byte|next|init|prng_newstate|random|crypto|rng_seed_int|ARC4next|ARC4init|str2binb|core_sha256|binb2hex|Utf8Encode|0xF|hexcase|mask|Maj|Sigma0256|Ch|Sigma1256|Gamma0256|Gamma1256|msw|successful|Authentication|been|has|User|aes|hash|srp|join|slice|split|appendChild|head|javascript|text|createElement|confirmed|could|Verifier|ok|verifier|_|indexOf|concat|encode|base64|cipher|getPaddedBlock|convertStringToByteArray||toNumbers|md5|sha1|handshake|failed||send|close|Connection|urlencoded|form|www|application|POST|open|onreadystatechange|supported|catch|XMLHTTP|try|undefined|nodeValue|firstChild|django|calcX|getN|getg|geturl|getxhr|getI|c46d46600d87fef149bd79b81119842f3c20241fda67d06ef412d8f6d9479c58|115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3|gcd|modInverse|divideAndRemainder|remainder|flipBit|clearBit|setBit|bitCount|andNot|xor|or|and|equals|toByteArray|shortValue|byteValue|509|503|499|491|487|479|467|463|461|457|449|443|439|433|431|421|419||409|401|397|389|383|379|373|367|359|353|349|347|337|331|317|313|311|307|293|283|281|277|271|269|263|257|251|241|239|233|229|227|223|211|199|197|193|191|181|179|173|167|163|157|151|149|139|137|131|113|109|107|103|101|768|144|substr|log|LN2|0xffffffff|0123456789abcdefghijklmnopqrstuvwxyz|Explorer|Internet|0xfffffff|0x3ffffff|0x4000000||0xefcafe|0xffffff|0xdeadbeefcafe|65536|appVersion|getTime|Date|0123456789abcdef|0123456789ABCDEF||224|192|2048|0x5BE0CD19|0x1F83D9AB|0x9B05688C|0x510E527F|0xA54FF53A|0x3C6EF372|0xBB67AE85|0x6A09E667|0xC67178F2|0xBEF9A3F7|0xA4506CEB|0x90BEFFFA|0x8CC70208|0x84C87814|0x78A5636F|0x748F82EE|0x682E6FF3|0x5B9CCA4F|0x4ED8AA4A|0x391C0CB3|0x34B0BCB5|0x2748774C|0x1E376C08|0x19A4C116|0x106AA070|0xF40E3585|0xD6990624|0xD192E819|0xC76C51A3|0xC24B8B70|0xA81A664B|0xA2BFE8A1|0x92722C85|0x81C2C92E|0x766A0ABB|0x650A7354|0x53380D13|0x4D2C6DFC|0x2E1B2138|0x27B70A85|0x14292967|0x6CA6351|0xD5A79147|0xC6E00BF3|0xBF597FC7|0xB00327C8||0xA831C66D|0x983E5152|0x76F988DA||0x5CB0A9DC|0x4A7484AA|0x2DE92C6F|0x240CA1CC|0xFC19DC6|0xEFBE4786|0xE49B69C1||0xC19BF174|0x9BDC06A7|0x80DEB1FE|0x72BE5D74|0x550C7DC3||0x243185BE|0x12835B01|0xD807AA98|0xAB1C5ED5|0x923F82A4|0x59F111F1|0x3956C25B|0xE9B5DBA5|0xB5C0FBCF|0x71374491|0x428A2F98'.split('|'),0,{}))
diff --git a/javascript/srp.js b/javascript/srp.js
index ba14324..58a3fe7 100644
--- a/javascript/srp.js
+++ b/javascript/srp.js
@@ -209,13 +209,28 @@ function SRP(username, password, ser, base_url)
hashfun = SHA1;
else if(algo == "md5")
hashfun = MD5;
- alert(hashfun(dsalt+p));
+ //alert(hashfun(dsalt+p));
calculations(s, ephemeral, hashfun(dsalt+p));
that.ajaxRequest(url+that.paths("upgrade/authenticate/"), "M="+M, confirm_upgrade);
};
window.setTimeout(do_upgrade,10);
};
+ // Encrypt plaintext using slowAES
+ function encrypt(plaintext)
+ {
+ var key = cryptoHelpers.toNumbers(that.key());
+ var byteMessage = cryptoHelpers.convertStringToByteArray(plaintext);
+ var iv = new Array(16);
+ rng.nextBytes(iv);
+ var paddedByteMessage = slowAES.getPaddedBlock(byteMessage, 0, byteMessage.length, slowAES.modeOfOperation.CFB);
+ var ciphertext = slowAES.encrypt(paddedByteMessage, slowAES.modeOfOperation.CFB, key, key.length, iv).cipher;
+ var retstring = cryptoHelpers.base64.encode(iv.concat(ciphertext));
+ while(retstring.indexOf("+",0) > -1)
+ retstring = retstring.replace("+", "_");
+ return retstring;
+ };
+
// Receive the server's M, confirming that the server has HASH(p)
// Next, send P in plaintext (this is the **only** time it should ever be sent plain text)
function confirm_upgrade()
@@ -225,8 +240,9 @@ function SRP(username, password, ser, base_url)
{
if(that.innerxml(xhr.responseXML.getElementsByTagName("M")[0]) == M2)
{
+ K = SHA256(S.toString(16));
var auth_url = url + that.paths("upgrade/verifier/");
- that.ajaxRequest(auth_url, "p="+p, confirm_verifier);
+ that.ajaxRequest(auth_url, "p="+encrypt(p)+"&l="+p.length, confirm_verifier);
}
else
that.error_message("Server key does not match");
@@ -242,6 +258,7 @@ function SRP(username, password, ser, base_url)
function confirm_verifier()
{
if(xhr.readyState == 4 && xhr.status == 200) {
+ K = null;
if(xhr.responseXML.getElementsByTagName("ok").length > 0)
that.identify();
else
@@ -273,6 +290,8 @@ function SRP(username, password, ser, base_url)
{
import_file(path+"/MD5.js");
import_file(path+"/SHA1.js");
+ import_file(path+"/cryptoHelpers.js");
+ import_file(path+"/aes.js");
}
}
// If someone wants to use the session key for encrypting traffic, they can
@@ -282,7 +301,7 @@ function SRP(username, password, ser, base_url)
if(K == null)
if(authenticated)
{
- K = SHA256(S);
+ K = SHA256(S.toString(16));
return K;
}
else