From 9f4df576797892f3efc64ee54fc804b5ad3cf4d3 Mon Sep 17 00:00:00 2001 From: Sean Colyer Date: Wed, 5 Sep 2012 21:59:31 -0400 Subject: [PATCH] Added more jsdoc. --- doc/JXG.Util.html | 14 +- doc/global.html | 118 +- doc/index.html | 6 +- doc/openpgp.html | 22 +- resources/openpgp.js | 18466 ++++++++++++++++---------------- resources/openpgp.min.js | 773 +- src/openpgp.keyring.js | 36 +- src/openpgp.msg.message.js | 24 +- src/openpgp.msg.privatekey.js | 7 +- src/openpgp.msg.publickey.js | 4 + 10 files changed, 9754 insertions(+), 9716 deletions(-) diff --git a/doc/JXG.Util.html b/doc/JXG.Util.html index 9e00a877..cc5783f6 100644 --- a/doc/JXG.Util.html +++ b/doc/JXG.Util.html @@ -78,7 +78,7 @@ The code is based on the source code for gunzip.c by Pasi Ojala
Source:
-
+
@@ -157,7 +157,7 @@ The code is based on the source code for gunzip.c by Pasi Ojala
Source:
-
+
@@ -232,7 +232,7 @@ EXAMPLES:
Source:
-
+
@@ -291,7 +291,7 @@ EXAMPLES:
Source:
-
+
@@ -396,7 +396,7 @@ EXAMPLES:
Source:
-
+
@@ -454,13 +454,13 @@ EXAMPLES:
diff --git a/doc/global.html b/doc/global.html index f01a09bd..b0921375 100644 --- a/doc/global.html +++ b/doc/global.html @@ -118,7 +118,7 @@
Source:
-
+
@@ -166,7 +166,7 @@
Source:
-
+
@@ -215,7 +215,7 @@ configuration was in place
Source:
-
+
@@ -263,7 +263,7 @@ configuration was in place
Source:
-
+
@@ -311,7 +311,7 @@ configuration was in place
Source:
-
+
@@ -413,7 +413,7 @@ configuration was in place
Source:
-
+
@@ -525,7 +525,7 @@ configuration was in place
Source:
-
+
@@ -594,7 +594,7 @@ configuration was in place
Source:
-
+
@@ -706,7 +706,7 @@ configuration was in place
Source:
-
+
@@ -818,7 +818,7 @@ configuration was in place
Source:
-
+
@@ -936,7 +936,7 @@ configuration was in place
Source:
-
+
@@ -1048,7 +1048,7 @@ configuration was in place
Source:
-
+
@@ -1160,7 +1160,7 @@ configuration was in place
Source:
-
+
@@ -1239,7 +1239,7 @@ warranty of any kind.
Source:
-
+
@@ -1423,7 +1423,7 @@ blockcipher to decrypt a message
Source:
-
+
@@ -1636,7 +1636,7 @@ using the specified blockcipher to encrypt a message
Source:
-
+
@@ -1802,7 +1802,7 @@ using the specified blockcipher to encrypt a message
Source:
-
+
@@ -1879,7 +1879,7 @@ openpgp.config.config
Source:
-
+
@@ -2036,7 +2036,7 @@ the specified secretMPIs of the private key and the specified algorithm.
Source:
-
+
@@ -2185,7 +2185,7 @@ and the specified algorithm.
Source:
-
+
@@ -2255,7 +2255,7 @@ openpgp_type_mpi is returned; otherwise null
Source:
-
+
@@ -2375,7 +2375,7 @@ openpgp_type_mpi is returned; otherwise null
Source:
-
+
@@ -2487,7 +2487,7 @@ openpgp_type_mpi is returned; otherwise null
Source:
-
+
@@ -2599,7 +2599,7 @@ openpgp_type_mpi is returned; otherwise null
Source:
-
+
@@ -2730,7 +2730,7 @@ size of the cipher
Source:
-
+
@@ -2842,7 +2842,7 @@ size of the cipher
Source:
-
+
@@ -2954,7 +2954,7 @@ size of the cipher
Source:
-
+
@@ -3084,7 +3084,7 @@ size of the cipher
Source:
-
+
@@ -3214,7 +3214,7 @@ size of the cipher
Source:
-
+
@@ -3362,7 +3362,7 @@ size of the cipher
Source:
-
+
@@ -3546,7 +3546,7 @@ size of the cipher
Source:
-
+
@@ -3714,7 +3714,7 @@ otherwise use without the resync (for MDC encrypted data)
Source:
-
+
@@ -3902,7 +3902,7 @@ to retrieve that string
Source:
-
+
@@ -4082,7 +4082,7 @@ to retrieve that string
Source:
-
+
@@ -4248,7 +4248,7 @@ to retrieve that string
Source:
-
+
@@ -4340,7 +4340,7 @@ packet block.
Source:
-
+
@@ -4453,7 +4453,7 @@ This function decodes a String(message) in base64 (radix-64)
Source:
-
+
@@ -4566,7 +4566,7 @@ This function encodes a String (message) in base64 (radix-64)
Source:
-
+
@@ -4635,7 +4635,7 @@ This function encodes a String (message) in base64 (radix-64)
Source:
-
+
@@ -4748,7 +4748,7 @@ and an attribute "openpgp" containing the bytes.
Source:
-
+
@@ -4878,7 +4878,7 @@ and an attribute "openpgp" containing the bytes.
Source:
-
+
@@ -4990,7 +4990,7 @@ and an attribute "openpgp" containing the bytes.
Source:
-
+
@@ -5138,7 +5138,7 @@ and an attribute "openpgp" containing the bytes.
Source:
-
+
@@ -5251,7 +5251,7 @@ This function escapes HTML characters within a string. This is used to prevent X
Source:
-
+
@@ -5591,7 +5591,7 @@ major versions. Consequently, this section is complex.
Source:
-
+
@@ -6112,7 +6112,7 @@ specifies the length of the User ID.
Source:
-
+
@@ -6177,7 +6177,7 @@ specifies the length of the User ID.
Source:
-
+
@@ -6241,7 +6241,7 @@ String-to-key (S2K) specifiers are used to convert passphrase strings
Source:
-
+
@@ -6348,7 +6348,7 @@ are automatically converted to HTML line feeds '
'
Source:
-
+
@@ -6466,7 +6466,7 @@ Different than print_debug because will call hexstrdump iff necessary.
Source:
-
+
@@ -6581,7 +6581,7 @@ are automatically converted to HTML line feeds '
'
Source:
-
+
@@ -6696,7 +6696,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -6826,7 +6826,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -6948,7 +6948,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -7070,7 +7070,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -7192,7 +7192,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -7322,7 +7322,7 @@ are automatically converted to HTML line feeds '
'.
Source:
-
+
@@ -7368,13 +7368,13 @@ are automatically converted to HTML line feeds '
'.
diff --git a/doc/index.html b/doc/index.html index 4e2a7cb1..5968c523 100644 --- a/doc/index.html +++ b/doc/index.html @@ -85,7 +85,7 @@
Source:
-
+
@@ -127,13 +127,13 @@
diff --git a/doc/openpgp.html b/doc/openpgp.html index 1f4c292d..3f27f34d 100644 --- a/doc/openpgp.html +++ b/doc/openpgp.html @@ -78,7 +78,7 @@ from the beginning. To use this library call "openpgp.init()"
Source:
-
+
@@ -243,7 +243,7 @@ from the beginning. To use this library call "openpgp.init()"
Source:
-
+
@@ -322,7 +322,7 @@ from the beginning. To use this library call "openpgp.init()"
Source:
-
+
@@ -438,7 +438,7 @@ returns an array of message objects
Source:
-
+
@@ -568,7 +568,7 @@ the private key(s)
Source:
-
+
@@ -698,7 +698,7 @@ the public key(s)
Source:
-
+
@@ -849,7 +849,7 @@ keys to be used to encrypt the message
Source:
-
+
@@ -1021,7 +1021,7 @@ with the specified private key.
Source:
-
+
@@ -1171,7 +1171,7 @@ key to be used to sign the message
Source:
-
+
@@ -1231,13 +1231,13 @@ key to be used to sign the message
diff --git a/resources/openpgp.js b/resources/openpgp.js index bcc8ba58..77c3ab6e 100644 --- a/resources/openpgp.js +++ b/resources/openpgp.js @@ -16,785 +16,105 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /** - * GPG4Browsers Core interface. A single instance is hold - * from the beginning. To use this library call "openpgp.init()" - * @alias openpgp - * @class - * @classdesc Main Openpgp.js class. Use this to initiate and make all calls to this library. - */ -function _openpgp () { - this.tostring = ""; - - /** - * initializes the library: - * - reading the keyring from local storage - * - reading the config from local storage - * @return [void] - */ - function init() { - this.config = new openpgp_config(); - this.config.read(); - this.keyring = new openpgp_keyring(); - this.keyring.init(); - } - - /** - * reads several publicKey objects from a ascii armored - * representation an returns openpgp_msg_publickey packets - * @param {String} armoredText OpenPGP armored text containing - * the public key(s) - * @return {Array[openpgp_msg_publickey]} on error the function - * returns null - */ - function read_publicKey(armoredText) { - var mypos = 0; - var publicKeys = new Array(); - var publicKeyCount = 0; - var input = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')).openpgp; - var l = input.length; - while (mypos != input.length) { - var first_packet = openpgp_packet.read_packet(input, mypos, l); - // public key parser - if (input[mypos].charCodeAt() == 0x99 || first_packet.tagType == 6) { - publicKeys[publicKeyCount] = new openpgp_msg_publickey(); - publicKeys[publicKeyCount].header = input.substring(mypos,mypos+3); - if (input[mypos].charCodeAt() == 0x99) { - // parse the length and read a tag6 packet - mypos++; - var l = (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - publicKeys[publicKeyCount].publicKeyPacket = new openpgp_packet_keymaterial(); - publicKeys[publicKeyCount].publicKeyPacket.header = publicKeys[publicKeyCount].header; - publicKeys[publicKeyCount].publicKeyPacket.read_tag6(input, mypos, l); - mypos += publicKeys[publicKeyCount].publicKeyPacket.packetLength; - mypos += publicKeys[publicKeyCount].read_nodes(publicKeys[publicKeyCount].publicKeyPacket, input, mypos, (input.length - mypos)); - } else { - publicKeys[publicKeyCount] = new openpgp_msg_publickey(); - publicKeys[publicKeyCount].publicKeyPacket = first_packet; - mypos += first_packet.headerLength+first_packet.packetLength; - mypos += publicKeys[publicKeyCount].read_nodes(first_packet, input, mypos, input.length -mypos); - } - } else { - util.print_error("no public key found!"); - return null; - } - publicKeys[publicKeyCount].data = input.substring(0,mypos); - publicKeyCount++; - } - return publicKeys; - } - - /** - * reads several privateKey objects from a ascii armored - * representation an returns openpgp_msg_privatekey objects - * @param {String} armoredText OpenPGP armored text containing - * the private key(s) - * @return {Array[openpgp_msg_privatekey]} on error the function - * returns null - */ - function read_privateKey(armoredText) { - var privateKeys = new Array(); - var privateKeyCount = 0; - var mypos = 0; - var input = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')).openpgp; - var l = input.length; - while (mypos != input.length) { - var first_packet = openpgp_packet.read_packet(input, mypos, l); - if (first_packet.tagType == 5) { - privateKeys[privateKeys.length] = new openpgp_msg_privatekey(); - mypos += first_packet.headerLength+first_packet.packetLength; - mypos += privateKeys[privateKeyCount].read_nodes(first_packet, input, mypos, l); - // other blocks - } else { - util.print_error('no block packet found!'); - return null; - } - privateKeys[privateKeyCount].data = input.substring(0,mypos); - privateKeyCount++; - } - return privateKeys; - } - - /** - * reads message packets out of an OpenPGP armored text and - * returns an array of message objects - * @param {String} armoredText text to be parsed - * @return {Array[openpgp_msg_message]} on error the function - * returns null - */ - function read_message(armoredText) { - var dearmored; - try{ - dearmored = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')); - } - catch(e){ - util.print_error('no message found!'); - return null; - } - var input = dearmored.openpgp; - var messages = new Array(); - var messageCount = 0; - var mypos = 0; - var l = input.length; - while (mypos < input.length) { - var first_packet = openpgp_packet.read_packet(input, mypos, l); - // public key parser (definition from the standard:) - // OpenPGP Message :- Encrypted Message | Signed Message | - // Compressed Message | Literal Message. - // Compressed Message :- Compressed Data Packet. - // - // Literal Message :- Literal Data Packet. - // - // ESK :- Public-Key Encrypted Session Key Packet | - // Symmetric-Key Encrypted Session Key Packet. - // - // ESK Sequence :- ESK | ESK Sequence, ESK. - // - // Encrypted Data :- Symmetrically Encrypted Data Packet | - // Symmetrically Encrypted Integrity Protected Data Packet - // - // Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data. - // - // One-Pass Signed Message :- One-Pass Signature Packet, - // OpenPGP Message, Corresponding Signature Packet. - - // Signed Message :- Signature Packet, OpenPGP Message | - // One-Pass Signed Message. - if (first_packet.tagType == 1 || - (first_packet.tagType == 2 && first_packet.signatureType < 16) || - first_packet.tagType == 3 || - first_packet.tagType == 8 || - first_packet.tagType == 9 || - first_packet.tagType == 10 || - first_packet.tagType == 11 || - first_packet.tagType == 18 || - first_packet.tagType == 19) { - messages[messages.length] = new openpgp_msg_message(); - messages[messageCount].messagePacket = first_packet; - messages[messageCount].type = dearmored.type; - // Encrypted Message - if (first_packet.tagType == 9 || - first_packet.tagType == 1 || - first_packet.tagType == 3 || - first_packet.tagType == 18) { - if (first_packet.tagType == 9) { - util.print_error("unexpected openpgp packet"); - break; - } else if (first_packet.tagType == 1) { - util.print_debug("session key found:\n "+first_packet.toString()); - var issessionkey = true; - messages[messageCount].sessionKeys = new Array(); - var sessionKeyCount = 0; - while (issessionkey) { - messages[messageCount].sessionKeys[sessionKeyCount] = first_packet; - mypos += first_packet.packetLength + first_packet.headerLength; - l -= (first_packet.packetLength + first_packet.headerLength); - first_packet = openpgp_packet.read_packet(input, mypos, l); - - if (first_packet.tagType != 1 && first_packet.tagType != 3) - issessionkey = false; - sessionKeyCount++; - } - if (first_packet.tagType == 18 || first_packet.tagType == 9) { - util.print_debug("encrypted data found:\n "+first_packet.toString()); - messages[messageCount].encryptedData = first_packet; - mypos += first_packet.packetLength+first_packet.headerLength; - l -= (first_packet.packetLength+first_packet.headerLength); - messageCount++; - - } else { - util.print_debug("something is wrong: "+first_packet.tagType); - } - - } else if (first_packet.tagType == 18) { - util.print_debug("symmetric encrypted data"); - break; - } - } else - // Signed Message - if (first_packet.tagType == 2 && first_packet.signatureType < 3) { - messages[messageCount].text = dearmored.text; - messages[messageCount].signature = first_packet; - break; - } else - // Compressed Message - // TODO: needs to be implemented. From a security perspective: this message is plaintext anyway. - if (first_packet.tagType == 8) { - util.print_error("A directly compressed message is currently not supported"); - break; - } else - // Marker Packet (Obsolete Literal Packet) (Tag 10) - // "Such a packet MUST be ignored when received." see http://tools.ietf.org/html/rfc4880#section-5.8 - if (first_packet.tagType == 10) { - // reset messages - messages.length = 0; - // continue with next packet - mypos += first_packet.packetLength + first_packet.headerLength; - l -= (first_packet.packetLength + first_packet.headerLength); - } else - // Literal Message - // TODO: needs to be implemented. From a security perspective: this message is plaintext anyway. - if (first_packet.tagType == 11) { - util.print_error("A direct literal message is currently not supported."); - break; - } - } else { - util.print_error('no message found!'); - return null; - } - } - - return messages; - } - - /** - * creates a binary string representation of an encrypted and signed message. - * The message will be encrypted with the public keys specified and signed - * with the specified private key. - * @param {obj: [openpgp_msg_privatekey]} privatekey private key to be used to sign the message - * @param {Array {obj: [openpgp_msg_publickey]}} publickeys public keys to be used to encrypt the message - * @param {String} messagetext message text to encrypt and sign - * @return {String} a binary string representation of the message which can be OpenPGP armored - */ - function write_signed_and_encrypted_message(privatekey, publickeys, messagetext) { - var result = ""; - var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); - util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); - for (var i = 0; i < publickeys.length; i++) { - var onepasssignature = new openpgp_packet_onepasssignature(); - var onepasssigstr = ""; - if (i == 0) - onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); - else - onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); - util.print_debug_hexstr_dump("onepasssigstr: |"+onepasssigstr+"|\n",onepasssigstr); - var datasignature = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"), privatekey); - util.print_debug_hexstr_dump("datasignature: |"+datasignature.openpgp+"|\n",datasignature.openpgp); - if (i == 0) { - result = onepasssigstr+literal+datasignature.openpgp; - } else { - result = onepasssigstr+result+datasignature.openpgp; - } - } - - util.print_debug_hexstr_dump("signed packet: |"+result+"|\n",result); - // signatures done.. now encryption - var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); - var result2 = ""; - - // creating session keys for each recipient - for (var i = 0; i < publickeys.length; i++) { - var pkey = publickeys[i].getEncryptionKey(); - if (pkey == null) { - util.print_error("no encryption key found! Key is for signing only."); - return null; - } - result2 += new openpgp_packet_encryptedsessionkey(). - write_pub_key_packet( - pkey.getKeyId(), - pkey.MPIs, - pkey.publicKeyAlgorithm, - openpgp.config.config.encryption_cipher, - sessionkey); - } - if (openpgp.config.config.integrity_protect) { - result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } else { - result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } - return openpgp_encoding_armor(3,result2,null,null); - } - /** - * creates a binary string representation of an encrypted message. - * The message will be encrypted with the public keys specified - * @param {Array {obj: [openpgp_msg_publickey]}} publickeys public - * keys to be used to encrypt the message - * @param {String} messagetext message text to encrypt - * @return {String} a binary string representation of the message - * which can be OpenPGP armored - */ - function write_encrypted_message(publickeys, messagetext) { - var result = ""; - var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); - util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); - result = literal; - - // signatures done.. now encryption - var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); - var result2 = ""; - - // creating session keys for each recipient - for (var i = 0; i < publickeys.length; i++) { - var pkey = publickeys[i].getEncryptionKey(); - if (pkey == null) { - util.print_error("no encryption key found! Key is for signing only."); - return null; - } - result2 += new openpgp_packet_encryptedsessionkey(). - write_pub_key_packet( - pkey.getKeyId(), - pkey.MPIs, - pkey.publicKeyAlgorithm, - openpgp.config.config.encryption_cipher, - sessionkey); - } - if (openpgp.config.config.integrity_protect) { - result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } else { - result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } - return openpgp_encoding_armor(3,result2,null,null); - } - - /** - * creates a binary string representation a signed message. - * The message will be signed with the specified private key. - * @param {obj: [openpgp_msg_privatekey]} privatekey private - * key to be used to sign the message - * @param {String} messagetext message text to sign - * @return {Object: text [String]}, openpgp: {String} a binary - * string representation of the message which can be OpenPGP - * armored(openpgp) and a text representation of the message (text). This can be directly used to OpenPGP armor the message - */ - function write_signed_message(privatekey, messagetext) { - var sig = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), privatekey); - var result = {text: messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), openpgp: sig.openpgp, hash: sig.hash}; - return openpgp_encoding_armor(2,result, null, null) - } - - /** - * generates a new key pair for openpgp. Beta stage. Currently only supports RSA keys, and no subkeys. - * @param {int} keyType to indicate what type of key to make. RSA is 1. Follows algorithms outlined in OpenPGP. - * @param {int} numBits number of bits for the key creation. (should be 1024+, generally) - * @param {string} userId assumes already in form of "User Name " - * @return {privateKey: [openpgp_msg_privatekey], privateKeyArmored: [string], publicKeyArmored: [string]} - */ - function generate_key_pair(keyType, numBits, userId, passphrase){ - var userIdPacket = new openpgp_packet_userid(); - var userIdString = userIdPacket.write_packet(userId); - - var keyPair = openpgp_crypto_generateKeyPair(keyType,numBits, passphrase, openpgp.config.config.prefer_hash_algorithm, 3); - var privKeyString = keyPair.privateKey; - var privKeyPacket = new openpgp_packet_keymaterial().read_priv_key(privKeyString.string,3,privKeyString.string.length); - if(!privKeyPacket.decryptSecretMPIs(passphrase)) - util.print_error('Issue creating key. Unable to read resulting private key'); - var privKey = new openpgp_msg_privatekey(); - privKey.privateKeyPacket = privKeyPacket; - privKey.getPreferredSignatureHashAlgorithm = function(){return openpgp.config.config.prefer_hash_algorithm};//need to override this to solve catch 22 to generate signature. 8 is value for SHA256 - - var publicKeyString = privKey.privateKeyPacket.publicKey.data; - var hashData = String.fromCharCode(0x99)+ String.fromCharCode(((publicKeyString.length) >> 8) & 0xFF) - + String.fromCharCode((publicKeyString.length) & 0xFF) +publicKeyString+String.fromCharCode(0xB4) + - String.fromCharCode((userId.length) >> 24) +String.fromCharCode(((userId.length) >> 16) & 0xFF) - + String.fromCharCode(((userId.length) >> 8) & 0xFF) + String.fromCharCode((userId.length) & 0xFF) + userId - var signature = new openpgp_packet_signature(); - signature = signature.write_message_signature(16,hashData, privKey); - var publicArmored = openpgp_encoding_armor(4, keyPair.publicKey.string + userIdString + signature.openpgp ); - - var privArmored = openpgp_encoding_armor(5,privKeyString.string+userIdString+signature.openpgp); - - return {privateKey : privKey, privateKeyArmored: privArmored, publicKeyArmored: publicArmored} - } - - this.generate_key_pair = generate_key_pair; - this.write_signed_message = write_signed_message; - this.write_signed_and_encrypted_message = write_signed_and_encrypted_message; - this.write_encrypted_message = write_encrypted_message; - this.read_message = read_message; - this.read_publicKey = read_publicKey; - this.read_privateKey = read_privateKey; - this.init = init; -} - -var openpgp = new _openpgp(); - - -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Public-Key Encrypted Session Key Packets (Tag 1) + * Implementation of the One-Pass Signature Packets (Tag 4) * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. + * RFC4880 5.4: + * The One-Pass Signature packet precedes the signed data and contains + * enough information to allow the receiver to begin calculating any + * hashes needed to verify the signature. It allows the Signature + * packet to be placed at the end of the message, so that the signer + * can compute the entire signed message in one pass. */ -function openpgp_packet_encryptedsessionkey() { +function openpgp_packet_onepasssignature() { + this.tagType = 4; + this.version = null; // A one-octet version number. The current version is 3. + this.type == null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. + this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) + this.publicKeyAlgorithm = null; // A one-octet number describing the public-key algorithm used. (See RFC4880 9.1) + this.signingKeyId = null; // An eight-octet number holding the Key ID of the signing key. + this.flags = null; // A one-octet number holding a flag showing whether the signature is nested. A zero value indicates that the next packet is another One-Pass Signature packet that describes another signature to be applied to the same message data. /** - * parsing function for a publickey encrypted session key packet (tag 1). - * - * @param input - * [string] payload of a tag 1 packet - * @param position - * [integer] position to start reading from the input string - * @param len - * [integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_pub_key_packet(input, position, len) { - this.tagType = 1; - this.packetLength = len; - var mypos = position; - if (len < 10) { - util - .print_error("openpgp.packet.encryptedsessionkey.js\n" + 'invalid length'); - return null; - } - - this.version = input[mypos++].charCodeAt(); - this.keyId = new openpgp_type_keyid(); - this.keyId.read_packet(input, mypos); - mypos += 8; - this.publicKeyAlgorithmUsed = input[mypos++].charCodeAt(); - - switch (this.publicKeyAlgorithmUsed) { - case 1: - case 2: // RSA - this.MPIs = new Array(); - this.MPIs[0] = new openpgp_type_mpi(); - this.MPIs[0].read(input, mypos, mypos - position); - break; - case 16: // Elgamal - this.MPIs = new Array(); - this.MPIs[0] = new openpgp_type_mpi(); - this.MPIs[0].read(input, mypos, mypos - position); - mypos += this.MPIs[0].packetLength; - this.MPIs[1] = new openpgp_type_mpi(); - this.MPIs[1].read(input, mypos, mypos - position); - break; - default: - util.print_error("openpgp.packet.encryptedsessionkey.js\n" - + "unknown public key packet algorithm type " - + this.publicKeyAlgorithmType); - break; - } - return this; - } - - /** - * create a string representation of a tag 1 packet - * - * @param publicKeyId - * [String] the public key id corresponding to publicMPIs key as - * string - * @param publicMPIs - * [Array[openpgp_type_mpi]] multiprecision integer objects - * describing the public key - * @param pubalgo - * [integer] the corresponding public key algorithm // See - * RFC4880 9.1 - * @param symmalgo - * [integer] the symmetric cipher algorithm used to encrypt the - * data within an encrypteddatapacket or - * encryptedintegrityprotecteddatapacket following this packet // - * See RFC4880 9.2 - * @param sessionkey - * [String] a string of randombytes representing the session key - * @return [String] the string representation - */ - function write_pub_key_packet(publicKeyId, publicMPIs, pubalgo, symmalgo, - sessionkey) { - var result = String.fromCharCode(3); - var data = String.fromCharCode(symmalgo); - data += sessionkey; - var checksum = util.calc_checksum(sessionkey); - data += String.fromCharCode((checksum >> 8) & 0xFF); - data += String.fromCharCode((checksum) & 0xFF); - result += publicKeyId; - result += String.fromCharCode(pubalgo); - var mpi = new openpgp_type_mpi(); - var mpiresult = openpgp_crypto_asymetricEncrypt(pubalgo, publicMPIs, - mpi.create(openpgp_encoding_eme_pkcs1_encode(data, - publicMPIs[0].mpiByteLength))); - for ( var i = 0; i < mpiresult.length; i++) { - result += mpiresult[i]; - } - result = openpgp_packet.write_packet_header(1, result.length) + result; - return result; - } - - /** - * parsing function for a symmetric encrypted session key packet (tag 3). - * - * @param input - * [string] payload of a tag 1 packet - * @param position - * [integer] position to start reading from the input string - * @param len - * [integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_symmetric_key_packet(input, position, len) { - this.tagType = 3; - var mypos = position; - // A one-octet version number. The only currently defined version is 4. - this.version = input[mypos++]; - - // A one-octet number describing the symmetric algorithm used. - this.symmetricKeyAlgorithmUsed = input[mypos++]; - // A string-to-key (S2K) specifier, length as defined above. - this.s2k = new openpgp_type_s2k(); - this.s2k.read(input, mypos); - - // Optionally, the encrypted session key itself, which is decrypted - // with the string-to-key object. - if ((s2k.s2kLength + mypos) < len) { - this.encryptedSessionKey = new Array(); - for ( var i = (mypos - position); i < len; i++) { - this.encryptedSessionKey[i] = input[mypos++]; - } - } - return this; - } - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param msg - * [openpgp_msg_message] the message object (with member - * encryptedData - * @param key - * [openpgp_msg_privatekey] private key with secMPIs unlocked - * @return [String] the unencrypted session key - */ - function decrypt(msg, key) { - if (this.tagType == 1) { - var result = openpgp_crypto_asymetricDecrypt( - this.publicKeyAlgorithmUsed, key.publicKey.MPIs, - key.secMPIs, this.MPIs).toMPI(); - var checksum = ((result.charCodeAt(result.length - 2) << 8) + result - .charCodeAt(result.length - 1)); - var decoded = openpgp_encoding_eme_pkcs1_decode(result.substring(2, result.length - 2), key.publicKey.MPIs[0].getByteLength()); - var sesskey = decoded.substring(1); - var algo = decoded.charCodeAt(0); - if (msg.encryptedData.tagType == 18) - return msg.encryptedData.decrypt(algo, sesskey); - else - return msg.encryptedData.decrypt_sym(algo, sesskey); - } else if (this.tagType == 3) { - util - .print_error("Symmetric encrypted sessionkey is not supported!"); - return null; - } - } - - /** - * Creates a string representation of this object (useful for debug - * purposes) - * - * @return the string containing a openpgp description - */ - function toString() { - if (this.tagType == 1) { - var result = '5.1. Public-Key Encrypted Session Key Packets (Tag 1)\n' - + ' KeyId: ' - + this.keyId.toString() - + '\n' - + ' length: ' - + this.packetLength - + '\n' - + ' version:' - + this.version - + '\n' - + ' pubAlgUs:' - + this.publicKeyAlgorithmUsed + '\n'; - for ( var i = 0; i < this.MPIs.length; i++) { - result += this.MPIs[i].toString(); - } - return result; - } else - return '5.3 Symmetric-Key Encrypted Session Key Packets (Tag 3)\n' - + ' KeyId: ' + this.keyId.toString() + '\n' - + ' length: ' + this.packetLength + '\n' - + ' version:' + this.version + '\n' + ' symKeyA:' - + this.symmetricKeyAlgorithmUsed + '\n' + ' s2k: ' - + this.s2k + '\n'; - } - - this.read_pub_key_packet = read_pub_key_packet; - this.read_symmetric_key_packet = read_symmetric_key_packet; - this.write_pub_key_packet = write_pub_key_packet; - this.toString = toString; - this.decrypt = decrypt; -}; - -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. - */ -function openpgp_packet_userattribute() { - this.tagType = 17; - this.certificationSignatures = new Array(); - this.certificationRevocationSignatures = new Array(); - this.revocationSignatures = new Array(); - this.parentNode = null; - - /** - * parsing function for a user attribute packet (tag 17). - * @param input [string] payload of a tag 17 packet + * parsing function for a one-pass signature packet (tag 4). + * @param input [string] payload of a tag 4 packet * @param position [integer] position to start reading from the input string * @param len [integer] length of the packet or the remaining length of input at position * @return [openpgp_packet_encrypteddata] object representation */ - function read_packet (input, position, len) { - var total_len = 0; + function read_packet(input, position, len) { this.packetLength = len; - this.userattributes = new Array(); - var count = 0; var mypos = position; - while (len != total_len) { - var current_len = 0; - // 4.2.2.1. One-Octet Lengths - if (input[mypos].charCodeAt() < 192) { - packet_length = input[mypos++].charCodeAt(); - current_len = 1; - // 4.2.2.2. Two-Octet Lengths - } else if (input[mypos].charCodeAt() >= 192 && input[mypos].charCodeAt() < 224) { - packet_length = ((input[mypos++].charCodeAt() - 192) << 8) - + (input[mypos++].charCodeAt()) + 192; - current_len = 2; - // 4.2.2.4. Partial Body Lengths - } else if (input[mypos].charCodeAt() > 223 && input[mypos].charCodeAt() < 255) { - packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); - current_len = 1; - // 4.2.2.3. Five-Octet Lengths - } else { - current_len = 5; - mypos++; - packet_length = (input[mypos++].charCodeAt() << 24) | (input[mypos++].charCodeAt() << 16) - | (input[mypos++].charCodeAt() << 8) | input[mypos++].charCodeAt(); - } - - var subpackettype = input[mypos++].charCodeAt(); - packet_length--; - current_len++; - this.userattributes[count] = new Array(); - this.userattributes[count] = input.substring(mypos, mypos + packet_length); - mypos += packet_length; - total_len += current_len+packet_length; - } - this.packetLength = mypos - position; + // A one-octet version number. The current version is 3. + this.version = input.charCodeAt(mypos++); + + // A one-octet signature type. Signature types are described in + // Section 5.2.1. + this.type = input.charCodeAt(mypos++); + + // A one-octet number describing the hash algorithm used. + this.hashAlgorithm = input.charCodeAt(mypos++); + + // A one-octet number describing the public-key algorithm used. + this.publicKeyAlgorithm = input.charCodeAt(mypos++); + // An eight-octet number holding the Key ID of the signing key. + this.signingKeyId = new openpgp_type_keyid(); + this.signingKeyId.read_packet(input,mypos); + mypos += 8; + + // A one-octet number holding a flag showing whether the signature + // is nested. A zero value indicates that the next packet is + // another One-Pass Signature packet that describes another + // signature to be applied to the same message data. + this.flags = input.charCodeAt(mypos++); return this; } - + /** - * generates debug output (pretty print) - * @return String which gives some information about the user attribute packet + * creates a string representation of a one-pass signature packet + * @param type [integer] Signature types as described in RFC4880 Section 5.2.1. + * @param hashalgorithm [integer] the hash algorithm used within the signature + * @param privatekey [openpgp_msg_privatekey] the private key used to generate the signature + * @param length [integer] length of data to be signed + * @param nested [boolean] boolean showing whether the signature is nested. + * "true" indicates that the next packet is another One-Pass Signature packet + * that describes another signature to be applied to the same message data. + * @return [String] a string representation of a one-pass signature packet */ - function toString() { - var result = '5.12. User Attribute Packet (Tag 17)\n'+ - ' AttributePackets: (count = '+this.userattributes.length+')\n'; - for (var i = 0; i < this.userattributes.length; i++) { - result += ' ('+this.userattributes[i].length+') bytes: ['+util.hexidump(this.userattributes[i])+']\n'; - } + function write_packet(type, hashalgorithm, privatekey,length, nested) { + var result =""; + + result += openpgp_packet.write_packet_header(4,13); + result += String.fromCharCode(3); + result += String.fromCharCode(type); + result += String.fromCharCode(hashalgorithm); + result += String.fromCharCode(privatekey.privateKeyPacket.publicKey.publicKeyAlgorithm); + result += privatekey.getKeyId(); + if (nested) + result += String.fromCharCode(0); + else + result += String.fromCharCode(1); + return result; } /** - * Continue parsing packets belonging to the user attribute packet such as signatures - * @param parent_node [openpgp_*] the parent object - * @param input [String] input string to read the packet(s) from - * @param position [integer] start position for the parser - * @param len [integer] length of the packet(s) or remaining length of input - * @return [integer] length of nodes read + * generates debug output (pretty print) + * @return String which gives some information about the one-pass signature packet */ - function read_nodes(parent_node, input, position, len) { - - this.parentNode = parent_node; - var exit = false; - var pos = position; - var l = len; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, l); - if (result == null) { - util.print_error("openpgp.packet.userattribute.js\n"+'[user_attr] parsing ends here @:' + pos + " l:" + l); - break; - } else { - switch (result.tagType) { - case 2: // Signature Packet - if (result.signatureType > 15 - && result.signatureType < 20) // certification - // // - // signature - this.certificationSignatures[this.certificationSignatures.length] = result; - else if (result.signatureType == 32) // certification revocation signature - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - pos += result.packetLength + result.headerLength; - l = len - (pos - position); - break; - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position; - return this.len; - break; - } - } - } - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position; - return this.len; - + function toString() { + return '5.4. One-Pass Signature Packets (Tag 4)\n'+ + ' length: '+this.packetLength+'\n'+ + ' type: '+this.type+'\n'+ + ' keyID: '+this.signingKeyId.toString()+'\n'+ + ' hashA: '+this.hashAlgorithm+'\n'+ + ' pubKeyA:'+this.publicKeyAlgorithm+'\n'+ + ' flags: '+this.flags+'\n'+ + ' version:'+this.version+'\n'; } this.read_packet = read_packet; - this.read_nodes = read_nodes; this.toString = toString; - + this.write_packet = write_packet; };// GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -813,26 +133,22 @@ function openpgp_packet_userattribute() { // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /** - * Implementation of the Symmetrically Encrypted Data Packet (Tag 9) + * Implementation of the strange "Marker packet" (Tag 10) * - * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted - * with a symmetric-key algorithm. When it has been decrypted, it contains other - * packets (usually a literal data packet or compressed data packet, but in - * theory other Symmetrically Encrypted Data packets or sequences of packets - * that form whole OpenPGP messages). + * RFC4880 5.8: An experimental version of PGP used this packet as the Literal + * packet, but no released version of PGP generated Literal packets with this + * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as + * the Marker packet. + * + * Such a packet MUST be ignored when received. */ - -function openpgp_packet_encrypteddata() { - this.tagType = 9; - this.packetLength = null; - this.encryptedData = null; - this.decryptedData = null; - +function openpgp_packet_marker() { + this.tagType = 10; /** - * parsing function for the packet. + * parsing function for a literal data packet (tag 10). * * @param input - * [string] payload of a tag 9 packet + * [string] payload of a tag 10 packet * @param position * [integer] position to start reading from the input string * @param len @@ -841,65 +157,28 @@ function openpgp_packet_encrypteddata() { * @return [openpgp_packet_encrypteddata] object representation */ function read_packet(input, position, len) { - var mypos = position; - this.packetLength = len; - // - Encrypted data, the output of the selected symmetric-key cipher - // operating in OpenPGP's variant of Cipher Feedback (CFB) mode. - this.encryptedData = input.substring(position, position + len); - return this; + this.packetLength = 3; + if (input[position].charCodeAt() == 0x50 && // P + input[position + 1].charCodeAt() == 0x47 && // G + input[position + 2].charCodeAt() == 0x50) // P + return this; + // marker packet does not contain "PGP" + return null; } /** - * symmetrically decrypt the packet data + * Generates Debug output * - * @param symmetric_algorithm_type - * [integer] symmetric key algorithm to use // See RFC4880 9.2 - * @param key - * [String] key as string with the corresponding length to the - * algorithm - * @return the decrypted data; + * @return String which gives some information about the keymaterial */ - function decrypt_sym(symmetric_algorithm_type, key) { - this.decryptedData = openpgp_crypto_symmetricDecrypt( - symmetric_algorithm_type, key, this.encryptedData, true); - util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n"+ - "data: "+util.hexstrdump(this.decryptedData)); - return this.decryptedData; - } - - /** - * Creates a string representation of the packet - * - * @param algo - * [Integer] symmetric key algorithm to use // See RFC4880 9.2 - * @param key - * [String] key as string with the corresponding length to the - * algorithm - * @param data - * [String] data to be - * @return [String] string-representation of the packet - */ - function write_packet(algo, key, data) { - var result = ""; - result += openpgp_crypto_symmetricEncrypt( - openpgp_crypto_getPrefixRandom(algo), algo, key, data, true); - result = openpgp_packet.write_packet_header(9, result.length) + result; - return result; - } - function toString() { - return '5.7. Symmetrically Encrypted Data Packet (Tag 9)\n' - + ' length: ' + this.packetLength + '\n' - + ' Used symmetric algorithm: ' + this.algorithmType + '\n' - + ' encrypted data: Bytes [' - + util.hexstrdump(this.encryptedData) + ']\n'; + return "5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)\n" + + " packet reads: \"PGP\"\n"; } - this.decrypt_sym = decrypt_sym; - this.toString = toString; + this.read_packet = read_packet; - this.write_packet = write_packet; -}; -// GPG4Browsers - An OpenPGP implementation in javascript + this.toString = toString; +}// GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // // This library is free software; you can redistribute it and/or @@ -1671,6 +950,1740 @@ function openpgp_packet_signature() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +/** + * Implementation of the Sym. Encrypted Integrity Protected Data Packet (Tag 18) + * + * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is + * a variant of the Symmetrically Encrypted Data packet. It is a new feature + * created for OpenPGP that addresses the problem of detecting a modification to + * encrypted data. It is used in combination with a Modification Detection Code + * packet. + */ + +function openpgp_packet_encryptedintegrityprotecteddata() { + this.tagType = 18; + this.version = null; // integer == 1 + this.packetLength = null; // integer + this.encryptedData = null; // string + this.decrytpedData = null; // string + this.hash = null; // string + /** + * parsing function for the packet. + * + * @param input + * [string] payload of a tag 18 packet + * @param position + * [integer] position to start reading from the input string + * @param len + * [integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encryptedintegrityprotecteddata] object + * representation + */ + function read_packet(input, position, len) { + this.packetLength = len; + // - A one-octet version number. The only currently defined value is + // 1. + this.version = input[position].charCodeAt(); + if (this.version != 1) { + util + .print_error('openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: ' + + this.version + + " , @ " + + position + + "hex:" + + util.hexstrdump(input)); + return null; + } + // - Encrypted data, the output of the selected symmetric-key cipher + // operating in Cipher Feedback mode with shift amount equal to the + // block size of the cipher (CFB-n where n is the block size). + this.encryptedData = input.substring(position + 1, position + 1 + len); + util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n" + + this.toString()); + return this; + } + + /** + * Creates a string representation of a Sym. Encrypted Integrity Protected + * Data Packet (tag 18) (see RFC4880 5.13) + * + * @param symmetric_algorithm + * [integer] the selected symmetric encryption algorithm to be + * used + * @param key + * [String] the key of cipher blocksize length to be used + * @param data + * plaintext data to be encrypted within the packet + * @return a string representation of the packet + */ + function write_packet(symmetric_algorithm, key, data) { + + var prefixrandom = openpgp_crypto_getPrefixRandom(symmetric_algorithm); + var prefix = prefixrandom + + prefixrandom.charAt(prefixrandom.length - 2) + + prefixrandom.charAt(prefixrandom.length - 1); + var tohash = data; + tohash += String.fromCharCode(0xD3); + tohash += String.fromCharCode(0x14); + util.print_debug_hexstr_dump("data to be hashed:" + , prefix + tohash); + tohash += str_sha1(prefix + tohash); + util.print_debug_hexstr_dump("hash:" + , tohash.substring(tohash.length - 20, + tohash.length)); + var result = openpgp_crypto_symmetricEncrypt(prefixrandom, + symmetric_algorithm, key, tohash, false).substring(0, + prefix.length + tohash.length); + var header = openpgp_packet.write_packet_header(18, result.length + 1) + + String.fromCharCode(1); + this.encryptedData = result; + return header + result; + } + + /** + * Decrypts the encrypted data contained in this object read_packet must + * have been called before + * + * @param symmetric_algorithm_type + * [integer] the selected symmetric encryption algorithm to be + * used + * @param key + * [String] the key of cipher blocksize length to be used + * @return the decrypted data of this packet + */ + function decrypt(symmetric_algorithm_type, key) { + this.decryptedData = openpgp_crypto_symmetricDecrypt( + symmetric_algorithm_type, key, this.encryptedData, false); + // there must be a modification detection code packet as the + // last packet and everything gets hashed except the hash itself + this.hash = str_sha1(openpgp_crypto_MDCSystemBytes( + symmetric_algorithm_type, key, this.encryptedData) + + this.decryptedData.substring(0, + this.decryptedData.length - 20)); + util.print_debug_hexstr_dump("calc hash = ", this.hash); + if (this.hash == this.decryptedData.substring( + this.decryptedData.length - 20, this.decryptedData.length)) + return this.decryptedData; + else + util + .print_error("Decryption stopped: discovered a modification of encrypted data."); + return null; + } + + function toString() { + var data = ''; + if(openpgp.config.debug) + data = ' data: Bytes [' + + util.hexstrdump(this.encryptedData) + ']'; + + return '5.13. Sym. Encrypted Integrity Protected Data Packet (Tag 18)\n' + + ' length: ' + + this.packetLength + + '\n' + + ' version: ' + + this.version + + '\n' + + data; + } + + this.write_packet = write_packet; + this.read_packet = read_packet; + this.toString = toString; + this.decrypt = decrypt; +}; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the Modification Detection Code Packet (Tag 19) + * + * RFC4880 5.14: The Modification Detection Code packet contains a SHA-1 hash of + * plaintext data, which is used to detect message modification. It is only used + * with a Symmetrically Encrypted Integrity Protected Data packet. The + * Modification Detection Code packet MUST be the last packet in the plaintext + * data that is encrypted in the Symmetrically Encrypted Integrity Protected + * Data packet, and MUST appear in no other place. + */ + +function openpgp_packet_modificationdetectioncode() { + this.tagType = 19; + this.hash = null; + /** + * parsing function for a modification detection code packet (tag 19). + * + * @param input + * [String] payload of a tag 19 packet + * @param position + * [Integer] position to start reading from the input string + * @param len + * [Integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_packet(input, position, len) { + this.packetLength = len; + + if (len != 20) { + util + .print_error("openpgp.packet.modificationdetectioncode.js\n" + + 'invalid length for a modification detection code packet!' + + len); + return null; + } + // - A 20-octet SHA-1 hash of the preceding plaintext data of the + // Symmetrically Encrypted Integrity Protected Data packet, + // including prefix data, the tag octet, and length octet of the + // Modification Detection Code packet. + this.hash = input.substring(position, position + 20); + return this; + } + + /* + * this packet is created within the encryptedintegrityprotected packet + * function write_packet(data) { } + */ + + /** + * generates debug output (pretty print) + * + * @return String which gives some information about the modification + * detection code + */ + function toString() { + return '5.14 Modification detection code packet\n' + ' bytes (' + + this.hash.length + '): [' + util.hexstrdump(this.hash) + ']'; + } + this.read_packet = read_packet; + this.toString = toString; +}; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * A User ID packet consists of UTF-8 text that is intended to represent + * the name and email address of the key holder. By convention, it + * includes an RFC 2822 [RFC2822] mail name-addr, but there are no + * restrictions on its content. The packet length in the header + * specifies the length of the User ID. + */ + +function openpgp_packet_userid() { + this.tagType = 13; + this.certificationSignatures = new Array(); + this.certificationRevocationSignatures = new Array(); + this.revocationSignatures = new Array(); + this.parentNode = null; + + /** + * parsing function for a user id packet (tag 13). + * @param input [string] payload of a tag 13 packet + * @param position [integer] position to start reading from the input string + * @param len [integer] length of the packet or the remaining length of input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_packet(input, position, len) { + this.text = ''; + this.packetLength = len; + + for ( var i = 0; i < len; i++) { + this.text += input[position + i]; + } + return this; + } + + /** + * creates a string representation of the user id packet + * @param user_id [String] the user id as string ("John Doe 15 + && result.signatureType < 20) { // certification + // // + // signature + this.certificationSignatures[this.certificationSignatures.length] = result; + break; + } else if (result.signatureType == 48) {// certification revocation signature + this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; + break; + } else if (result.signatureType == 24) { // omg. standalone signature + this.certificationSignatures[this.certificationSignatures.length] = result; + break; + } else { + util.debug("unknown sig t: "+result.signatureType+"@"+(pos - (result.packetLength + result.headerLength))); + } + default: + this.data = input; + this.position = position - parent_node.packetLength; + this.len = pos - position -(result.headerLength + result.packetLength); + return this.len; + } + } + } + this.data = input; + this.position = position - parent_node.packetLength; + this.len = pos - position -(result.headerLength + result.packetLength); + return this.len; + } else if (parent_node.tagType == 5) { // secret Key + this.parentNode = parent_node; + var exit = false; + var pos = position; + while (input.length != pos) { + var result = openpgp_packet.read_packet(input, pos, l - (pos - position)); + if (result == null) { + util.print_error('parsing ends here @:' + pos + " l:" + l); + break; + } else { + pos += result.packetLength + result.headerLength; + l = input.length - pos; + switch (result.tagType) { + case 2: // Signature Packet certification signature + if (result.signatureType > 15 + && result.signatureType < 20) + this.certificationSignatures[this.certificationSignatures.length] = result; + // certification revocation signature + else if (result.signatureType == 48) + this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; + default: + this.data = input; + this.position = position - parent_node.packetLength; + this.len = pos - position -(result.headerLength + result.packetLength); + return this.len; + } + } + } + } else { + util.print_error("unknown parent node for a userId packet "+parent_node.tagType); + } + } + + /** + * generates debug output (pretty print) + * @return String which gives some information about the user id packet + */ + function toString() { + var result = ' 5.11. User ID Packet (Tag 13)\n' + ' text (' + + this.text.length + '): "' + this.text.replace("<", "<") + + '"\n'; + result +="certification signatures:\n"; + for (var i = 0; i < this.certificationSignatures.length; i++) { + result += " "+this.certificationSignatures[i].toString(); + } + result +="certification revocation signatures:\n"; + for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { + result += " "+this.certificationRevocationSignatures[i].toString(); + } + return result; + } + + /** + * lookup function to find certification revocation signatures + * @param keyId string containing the key id of the issuer of this signature + * @return a CertificationRevocationSignature if found; otherwise null + */ + function hasCertificationRevocationSignature(keyId) { + for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { + if ((this.certificationRevocationSignatures[i].version == 3 && + this.certificationRevocationSignatures[i].keyId == keyId) || + (this.certificationRevocationSignatures[i].version == 4 && + this.certificationRevocationSignatures[i].issuerKeyId == keyId)) + return this.certificationRevocationSignatures[i]; + } + return null; + } + + /** + * Verifies all certification signatures. This method does not consider possible revocation signatures. + * @param publicKeyPacket the top level key material + * @return an array of integers corresponding to the array of certification signatures. The meaning of each integer is the following: + * 0 = bad signature + * 1 = signature expired + * 2 = issuer key not available + * 3 = revoked + * 4 = signature valid + * 5 = signature by key owner expired + * 6 = signature by key owner revoked + */ + function verifyCertificationSignatures(publicKeyPacket) { + result = new Array(); + for (var i = 0 ; i < this.certificationSignatures.length; i++) { + // A certification signature (type 0x10 through 0x13) hashes the User + // ID being bound to the key into the hash context after the above + // data. A V3 certification hashes the contents of the User ID or + // attribute packet packet, without any header. A V4 certification + // hashes the constant 0xB4 for User ID certifications or the constant + // 0xD1 for User Attribute certifications, followed by a four-octet + // number giving the length of the User ID or User Attribute data, and + // then the User ID or User Attribute data. + + if (this.certificationSignatures[i].version == 4) { + if (this.certificationSignatures[i].signatureExpirationTime != null && + this.certificationSignatures[i].signatureExpirationTime != null && + this.certificationSignatures[i].signatureExpirationTime != 0 && + !this.certificationSignatures[i].signatureNeverExpires && + new Date(this.certificationSignatures[i].creationTime.getTime() +(this.certificationSignatures[i].signatureExpirationTime*1000)) < new Date()) { + if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) + result[i] = 5; + else + result[i] = 1; + continue; + } + if (this.certificationSignatures[i].issuerKeyId == null) { + result[i] = 0; + continue; + } + var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].issuerKeyId); + if (issuerPublicKey == null || issuerPublicKey.length == 0) { + result[i] = 2; + continue; + } + // TODO: try to verify all returned issuer public keys (key ids are not unique!) + var issuerPublicKey = issuerPublicKey[0]; + var signingKey = issuerPublicKey.obj.getSigningKey(); + if (signingKey == null) { + result[i] = 0; + continue; + } + var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].issuerKeyId); + if (revocation != null && revocation.creationTime > + this.certificationSignatures[i].creationTime) { + var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ + publicKeyPacket.data+String.fromCharCode(0xB4)+ + String.fromCharCode((this.text.length >> 24) & 0xFF)+ + String.fromCharCode((this.text.length >> 16) & 0xFF)+ + String.fromCharCode((this.text.length >> 8) & 0xFF)+ + String.fromCharCode((this.text.length) & 0xFF)+ + this.text; + if (revocation.verify(signaturedata, signingKey)) { + if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) + result[i] = 6; + else + result[i] = 3; + continue; + } + } + var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ + publicKeyPacket.data+String.fromCharCode(0xB4)+ + String.fromCharCode((this.text.length >> 24) & 0xFF)+ + String.fromCharCode((this.text.length >> 16) & 0xFF)+ + String.fromCharCode((this.text.length >> 8) & 0xFF)+ + String.fromCharCode((this.text.length) & 0xFF)+ + this.text; + if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { + result[i] = 4; + } else + result[i] = 0; + } else if (this.certificationSignatures[i].version == 3) { + if (this.certificationSignatures[i].keyId == null) { + result[i] = 0; + continue; + } + var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].keyId); + if (issuerPublicKey == null || issuerPublicKey.length == 0) { + result[i] = 2; + continue; + } + issuerPublicKey = issuerPublicKey[0]; + var signingKey = publicKey.obj.getSigningKey(); + if (signingKey == null) { + result[i] = 0; + continue; + } + var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].keyId); + if (revocation != null && revocation.creationTime > + this.certificationSignatures[i].creationTime) { + var signaturedata = String.fromCharCode(0x99)+ this.publicKeyPacket.header.substring(1)+ + this.publicKeyPacket.data+this.text; + if (revocation.verify(signaturedata, signingKey)) { + if (revocation.keyId == publicKeyPacket.getKeyId()) + result[i] = 6; + else + result[i] = 3; + continue; + } + } + var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ + publicKeyPacket.data+this.text; + if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { + result[i] = 4; + } else + result[i] = 0; + } else { + result[i] = 0; + } + } + return result; + } + + /** + * verifies the signatures of the user id + * @return 0 if the userid is valid; 1 = userid expired; 2 = userid revoked + */ + function verify(publicKeyPacket) { + var result = this.verifyCertificationSignatures(publicKeyPacket); + if (result.indexOf(6) != -1) + return 2; + if (result.indexOf(5) != -1) + return 1; + return 0; + } + + // TODO: implementation missing + function addCertification(publicKeyPacket, privateKeyPacket) { + + } + + // TODO: implementation missing + function revokeCertification(publicKeyPacket, privateKeyPacket) { + + } + + this.hasCertificationRevocationSignature = hasCertificationRevocationSignature; + this.verifyCertificationSignatures = verifyCertificationSignatures; + this.verify = verify; + this.read_packet = read_packet; + this.write_packet = write_packet; + this.toString = toString; + this.read_nodes = read_nodes; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Public-Key Encrypted Session Key Packets (Tag 1) + * + * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key + * used to encrypt a message. Zero or more Public-Key Encrypted Session Key + * packets and/or Symmetric-Key Encrypted Session Key packets may precede a + * Symmetrically Encrypted Data Packet, which holds an encrypted message. The + * message is encrypted with the session key, and the session key is itself + * encrypted and stored in the Encrypted Session Key packet(s). The + * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted + * Session Key packet for each OpenPGP key to which the message is encrypted. + * The recipient of the message finds a session key that is encrypted to their + * public key, decrypts the session key, and then uses the session key to + * decrypt the message. + */ +function openpgp_packet_encryptedsessionkey() { + + /** + * parsing function for a publickey encrypted session key packet (tag 1). + * + * @param input + * [string] payload of a tag 1 packet + * @param position + * [integer] position to start reading from the input string + * @param len + * [integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_pub_key_packet(input, position, len) { + this.tagType = 1; + this.packetLength = len; + var mypos = position; + if (len < 10) { + util + .print_error("openpgp.packet.encryptedsessionkey.js\n" + 'invalid length'); + return null; + } + + this.version = input[mypos++].charCodeAt(); + this.keyId = new openpgp_type_keyid(); + this.keyId.read_packet(input, mypos); + mypos += 8; + this.publicKeyAlgorithmUsed = input[mypos++].charCodeAt(); + + switch (this.publicKeyAlgorithmUsed) { + case 1: + case 2: // RSA + this.MPIs = new Array(); + this.MPIs[0] = new openpgp_type_mpi(); + this.MPIs[0].read(input, mypos, mypos - position); + break; + case 16: // Elgamal + this.MPIs = new Array(); + this.MPIs[0] = new openpgp_type_mpi(); + this.MPIs[0].read(input, mypos, mypos - position); + mypos += this.MPIs[0].packetLength; + this.MPIs[1] = new openpgp_type_mpi(); + this.MPIs[1].read(input, mypos, mypos - position); + break; + default: + util.print_error("openpgp.packet.encryptedsessionkey.js\n" + + "unknown public key packet algorithm type " + + this.publicKeyAlgorithmType); + break; + } + return this; + } + + /** + * create a string representation of a tag 1 packet + * + * @param publicKeyId + * [String] the public key id corresponding to publicMPIs key as + * string + * @param publicMPIs + * [Array[openpgp_type_mpi]] multiprecision integer objects + * describing the public key + * @param pubalgo + * [integer] the corresponding public key algorithm // See + * RFC4880 9.1 + * @param symmalgo + * [integer] the symmetric cipher algorithm used to encrypt the + * data within an encrypteddatapacket or + * encryptedintegrityprotecteddatapacket following this packet // + * See RFC4880 9.2 + * @param sessionkey + * [String] a string of randombytes representing the session key + * @return [String] the string representation + */ + function write_pub_key_packet(publicKeyId, publicMPIs, pubalgo, symmalgo, + sessionkey) { + var result = String.fromCharCode(3); + var data = String.fromCharCode(symmalgo); + data += sessionkey; + var checksum = util.calc_checksum(sessionkey); + data += String.fromCharCode((checksum >> 8) & 0xFF); + data += String.fromCharCode((checksum) & 0xFF); + result += publicKeyId; + result += String.fromCharCode(pubalgo); + var mpi = new openpgp_type_mpi(); + var mpiresult = openpgp_crypto_asymetricEncrypt(pubalgo, publicMPIs, + mpi.create(openpgp_encoding_eme_pkcs1_encode(data, + publicMPIs[0].mpiByteLength))); + for ( var i = 0; i < mpiresult.length; i++) { + result += mpiresult[i]; + } + result = openpgp_packet.write_packet_header(1, result.length) + result; + return result; + } + + /** + * parsing function for a symmetric encrypted session key packet (tag 3). + * + * @param input + * [string] payload of a tag 1 packet + * @param position + * [integer] position to start reading from the input string + * @param len + * [integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_symmetric_key_packet(input, position, len) { + this.tagType = 3; + var mypos = position; + // A one-octet version number. The only currently defined version is 4. + this.version = input[mypos++]; + + // A one-octet number describing the symmetric algorithm used. + this.symmetricKeyAlgorithmUsed = input[mypos++]; + // A string-to-key (S2K) specifier, length as defined above. + this.s2k = new openpgp_type_s2k(); + this.s2k.read(input, mypos); + + // Optionally, the encrypted session key itself, which is decrypted + // with the string-to-key object. + if ((s2k.s2kLength + mypos) < len) { + this.encryptedSessionKey = new Array(); + for ( var i = (mypos - position); i < len; i++) { + this.encryptedSessionKey[i] = input[mypos++]; + } + } + return this; + } + /** + * Decrypts the session key (only for public key encrypted session key + * packets (tag 1) + * + * @param msg + * [openpgp_msg_message] the message object (with member + * encryptedData + * @param key + * [openpgp_msg_privatekey] private key with secMPIs unlocked + * @return [String] the unencrypted session key + */ + function decrypt(msg, key) { + if (this.tagType == 1) { + var result = openpgp_crypto_asymetricDecrypt( + this.publicKeyAlgorithmUsed, key.publicKey.MPIs, + key.secMPIs, this.MPIs).toMPI(); + var checksum = ((result.charCodeAt(result.length - 2) << 8) + result + .charCodeAt(result.length - 1)); + var decoded = openpgp_encoding_eme_pkcs1_decode(result.substring(2, result.length - 2), key.publicKey.MPIs[0].getByteLength()); + var sesskey = decoded.substring(1); + var algo = decoded.charCodeAt(0); + if (msg.encryptedData.tagType == 18) + return msg.encryptedData.decrypt(algo, sesskey); + else + return msg.encryptedData.decrypt_sym(algo, sesskey); + } else if (this.tagType == 3) { + util + .print_error("Symmetric encrypted sessionkey is not supported!"); + return null; + } + } + + /** + * Creates a string representation of this object (useful for debug + * purposes) + * + * @return the string containing a openpgp description + */ + function toString() { + if (this.tagType == 1) { + var result = '5.1. Public-Key Encrypted Session Key Packets (Tag 1)\n' + + ' KeyId: ' + + this.keyId.toString() + + '\n' + + ' length: ' + + this.packetLength + + '\n' + + ' version:' + + this.version + + '\n' + + ' pubAlgUs:' + + this.publicKeyAlgorithmUsed + '\n'; + for ( var i = 0; i < this.MPIs.length; i++) { + result += this.MPIs[i].toString(); + } + return result; + } else + return '5.3 Symmetric-Key Encrypted Session Key Packets (Tag 3)\n' + + ' KeyId: ' + this.keyId.toString() + '\n' + + ' length: ' + this.packetLength + '\n' + + ' version:' + this.version + '\n' + ' symKeyA:' + + this.symmetricKeyAlgorithmUsed + '\n' + ' s2k: ' + + this.s2k + '\n'; + } + + this.read_pub_key_packet = read_pub_key_packet; + this.read_symmetric_key_packet = read_symmetric_key_packet; + this.write_pub_key_packet = write_pub_key_packet; + this.toString = toString; + this.decrypt = decrypt; +}; + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the Literal Data Packet (Tag 11) + * + * RFC4880 5.9: A Literal Data packet contains the body of a message; data that + * is not to be further interpreted. + */ +function openpgp_packet_literaldata() { + this.tagType = 11; + + /** + * parsing function for a literal data packet (tag 11). + * + * @param input + * [string] payload of a tag 11 packet + * @param position + * [integer] position to start reading from the input string + * @param len + * [integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_packet(input, position, len) { + this.packetLength = len; + // - A one-octet field that describes how the data is formatted. + + this.format = input[position]; + this.filename = input.substr(position + 2, input + .charCodeAt(position + 1)); + this.date = new Date(parseInt(input.substr(position + 2 + + input.charCodeAt(position + 1), 4)) * 1000); + this.data = input.substring(position + 6 + + input.charCodeAt(position + 1)); + return this; + } + + /** + * Creates a string representation of the packet + * + * @param data + * [String] the data to be inserted as body + * @return [String] string-representation of the packet + */ + function write_packet(data) { + data = data.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"); + this.filename = "msg.txt"; + this.date = new Date(); + this.format = 't'; + var result = openpgp_packet.write_packet_header(11, data.length + 6 + + this.filename.length); + result += this.format; + result += String.fromCharCode(this.filename.length); + result += this.filename; + result += String + .fromCharCode((Math.round(this.date.getTime() / 1000) >> 24) & 0xFF); + result += String + .fromCharCode((Math.round(this.date.getTime() / 1000) >> 16) & 0xFF); + result += String + .fromCharCode((Math.round(this.date.getTime() / 1000) >> 8) & 0xFF); + result += String + .fromCharCode(Math.round(this.date.getTime() / 1000) & 0xFF); + result += data; + this.data = data; + return result; + } + + /** + * generates debug output (pretty print) + * + * @return String which gives some information about the keymaterial + */ + function toString() { + return '5.9. Literal Data Packet (Tag 11)\n' + ' length: ' + + this.packetLength + '\n' + ' format: ' + this.format + + '\n' + ' filename:' + this.filename + '\n' + + ' date: ' + this.date + '\n' + ' data: |' + + this.data + '|\n' + ' rdata: |' + this.real_data + '|\n'; + } + + this.read_packet = read_packet; + this.toString = toString; + this.write_packet = write_packet; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the Symmetrically Encrypted Data Packet (Tag 9) + * + * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted + * with a symmetric-key algorithm. When it has been decrypted, it contains other + * packets (usually a literal data packet or compressed data packet, but in + * theory other Symmetrically Encrypted Data packets or sequences of packets + * that form whole OpenPGP messages). + */ + +function openpgp_packet_encrypteddata() { + this.tagType = 9; + this.packetLength = null; + this.encryptedData = null; + this.decryptedData = null; + + /** + * parsing function for the packet. + * + * @param input + * [string] payload of a tag 9 packet + * @param position + * [integer] position to start reading from the input string + * @param len + * [integer] length of the packet or the remaining length of + * input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_packet(input, position, len) { + var mypos = position; + this.packetLength = len; + // - Encrypted data, the output of the selected symmetric-key cipher + // operating in OpenPGP's variant of Cipher Feedback (CFB) mode. + this.encryptedData = input.substring(position, position + len); + return this; + } + + /** + * symmetrically decrypt the packet data + * + * @param symmetric_algorithm_type + * [integer] symmetric key algorithm to use // See RFC4880 9.2 + * @param key + * [String] key as string with the corresponding length to the + * algorithm + * @return the decrypted data; + */ + function decrypt_sym(symmetric_algorithm_type, key) { + this.decryptedData = openpgp_crypto_symmetricDecrypt( + symmetric_algorithm_type, key, this.encryptedData, true); + util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n"+ + "data: "+util.hexstrdump(this.decryptedData)); + return this.decryptedData; + } + + /** + * Creates a string representation of the packet + * + * @param algo + * [Integer] symmetric key algorithm to use // See RFC4880 9.2 + * @param key + * [String] key as string with the corresponding length to the + * algorithm + * @param data + * [String] data to be + * @return [String] string-representation of the packet + */ + function write_packet(algo, key, data) { + var result = ""; + result += openpgp_crypto_symmetricEncrypt( + openpgp_crypto_getPrefixRandom(algo), algo, key, data, true); + result = openpgp_packet.write_packet_header(9, result.length) + result; + return result; + } + + function toString() { + return '5.7. Symmetrically Encrypted Data Packet (Tag 9)\n' + + ' length: ' + this.packetLength + '\n' + + ' Used symmetric algorithm: ' + this.algorithmType + '\n' + + ' encrypted data: Bytes [' + + util.hexstrdump(this.encryptedData) + ']\n'; + } + this.decrypt_sym = decrypt_sym; + this.toString = toString; + this.read_packet = read_packet; + this.write_packet = write_packet; +}; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * The User Attribute packet is a variation of the User ID packet. It + * is capable of storing more types of data than the User ID packet, + * which is limited to text. Like the User ID packet, a User Attribute + * packet may be certified by the key owner ("self-signed") or any other + * key owner who cares to certify it. Except as noted, a User Attribute + * packet may be used anywhere that a User ID packet may be used. + * + * While User Attribute packets are not a required part of the OpenPGP + * standard, implementations SHOULD provide at least enough + * compatibility to properly handle a certification signature on the + * User Attribute packet. A simple way to do this is by treating the + * User Attribute packet as a User ID packet with opaque contents, but + * an implementation may use any method desired. + */ +function openpgp_packet_userattribute() { + this.tagType = 17; + this.certificationSignatures = new Array(); + this.certificationRevocationSignatures = new Array(); + this.revocationSignatures = new Array(); + this.parentNode = null; + + /** + * parsing function for a user attribute packet (tag 17). + * @param input [string] payload of a tag 17 packet + * @param position [integer] position to start reading from the input string + * @param len [integer] length of the packet or the remaining length of input at position + * @return [openpgp_packet_encrypteddata] object representation + */ + function read_packet (input, position, len) { + var total_len = 0; + this.packetLength = len; + this.userattributes = new Array(); + var count = 0; + var mypos = position; + while (len != total_len) { + var current_len = 0; + // 4.2.2.1. One-Octet Lengths + if (input[mypos].charCodeAt() < 192) { + packet_length = input[mypos++].charCodeAt(); + current_len = 1; + // 4.2.2.2. Two-Octet Lengths + } else if (input[mypos].charCodeAt() >= 192 && input[mypos].charCodeAt() < 224) { + packet_length = ((input[mypos++].charCodeAt() - 192) << 8) + + (input[mypos++].charCodeAt()) + 192; + current_len = 2; + // 4.2.2.4. Partial Body Lengths + } else if (input[mypos].charCodeAt() > 223 && input[mypos].charCodeAt() < 255) { + packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); + current_len = 1; + // 4.2.2.3. Five-Octet Lengths + } else { + current_len = 5; + mypos++; + packet_length = (input[mypos++].charCodeAt() << 24) | (input[mypos++].charCodeAt() << 16) + | (input[mypos++].charCodeAt() << 8) | input[mypos++].charCodeAt(); + } + + var subpackettype = input[mypos++].charCodeAt(); + packet_length--; + current_len++; + this.userattributes[count] = new Array(); + this.userattributes[count] = input.substring(mypos, mypos + packet_length); + mypos += packet_length; + total_len += current_len+packet_length; + } + this.packetLength = mypos - position; + return this; + } + + /** + * generates debug output (pretty print) + * @return String which gives some information about the user attribute packet + */ + function toString() { + var result = '5.12. User Attribute Packet (Tag 17)\n'+ + ' AttributePackets: (count = '+this.userattributes.length+')\n'; + for (var i = 0; i < this.userattributes.length; i++) { + result += ' ('+this.userattributes[i].length+') bytes: ['+util.hexidump(this.userattributes[i])+']\n'; + } + return result; + } + + /** + * Continue parsing packets belonging to the user attribute packet such as signatures + * @param parent_node [openpgp_*] the parent object + * @param input [String] input string to read the packet(s) from + * @param position [integer] start position for the parser + * @param len [integer] length of the packet(s) or remaining length of input + * @return [integer] length of nodes read + */ + function read_nodes(parent_node, input, position, len) { + + this.parentNode = parent_node; + var exit = false; + var pos = position; + var l = len; + while (input.length != pos) { + var result = openpgp_packet.read_packet(input, pos, l); + if (result == null) { + util.print_error("openpgp.packet.userattribute.js\n"+'[user_attr] parsing ends here @:' + pos + " l:" + l); + break; + } else { + switch (result.tagType) { + case 2: // Signature Packet + if (result.signatureType > 15 + && result.signatureType < 20) // certification + // // + // signature + this.certificationSignatures[this.certificationSignatures.length] = result; + else if (result.signatureType == 32) // certification revocation signature + this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; + pos += result.packetLength + result.headerLength; + l = len - (pos - position); + break; + default: + this.data = input; + this.position = position - parent_node.packetLength; + this.len = pos - position; + return this.len; + break; + } + } + } + this.data = input; + this.position = position - parent_node.packetLength; + this.len = pos - position; + return this.len; + + } + + this.read_packet = read_packet; + this.read_nodes = read_nodes; + this.toString = toString; + +};// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +function _openpgp_packet() { + /** + * Encodes a given integer of length to the openpgp length specifier to a + * string + * + * @param length + * [Integer] of the length to encode + * @return string with openpgp length representation + */ + function encode_length(length) { + result = ""; + if (length < 192) { + result += String.fromCharCode(length); + } else if (length > 191 && length < 8384) { + /* + * let a = (total data packet length) - 192 let bc = two octet + * representation of a let d = b + 192 + */ + result += String.fromCharCode(((length - 192) >> 8) + 192); + result += String.fromCharCode((length - 192) & 0xFF); + } else { + result += String.fromCharCode(255); + result += String.fromCharCode((length >> 24) & 0xFF); + result += String.fromCharCode((length >> 16) & 0xFF); + result += String.fromCharCode((length >> 8) & 0xFF); + result += String.fromCharCode(length & 0xFF); + } + return result; + } + this.encode_length = encode_length; + + /** + * Writes a packet header version 4 with the given tag_type and length to a + * string + * + * @param tag_type + * integer of tag type + * @param length + * integer length of the payload + * @return string of the header + */ + function write_packet_header(tag_type, length) { + /* we're only generating v4 packet headers here */ + var result = ""; + result += String.fromCharCode(0xC0 | tag_type); + result += encode_length(length); + return result; + } + + /** + * Writes a packet header Version 3 with the given tag_type and length to a + * string + * + * @param tag_type + * integer of tag type + * @param length + * integer length of the payload + * @return string of the header + */ + function write_old_packet_header(tag_type, length) { + var result = ""; + if (length < 256) { + result += String.fromCharCode(0x80 | (tag_type << 2)); + result += String.fromCharCode(length); + } else if (length < 65536) { + result += String.fromCharCode(0x80 | (tag_type << 2) | 1); + result += String.fromCharCode(length >> 8); + result += String.fromCharCode(length & 0xFF); + } else { + result += String.fromCharCode(0x80 | (tag_type << 2) | 2); + result += String.fromCharCode((length >> 24) & 0xFF); + result += String.fromCharCode((length >> 16) & 0xFF); + result += String.fromCharCode((length >> 8) & 0xFF); + result += String.fromCharCode(length & 0xFF); + } + return result; + } + this.write_old_packet_header = write_old_packet_header; + this.write_packet_header = write_packet_header; + /** + * Generic static Packet Parser function + * + * @param input + * [String] input stream as string + * @param position + * [integer] position to start parsing + * @param len + * [integer] length of the input from position on + * @return [openpgp_packet_*] returns a parsed openpgp_packet + */ + function read_packet(input, position, len) { + // some sanity checks + if (input == null || input.length <= position + || input.substring(position).length < 2 + || (input[position].charCodeAt() & 0x80) == 0) { + util + .print_error("Error during parsing. This message / key is propably not containing a valid OpenPGP format."); + return null; + } + var mypos = position; + var tag = -1; + var format = -1; + + format = 0; // 0 = old format; 1 = new format + if ((input[mypos].charCodeAt() & 0x40) != 0) { + format = 1; + } + + var packet_length_type; + if (format) { + // new format header + tag = input[mypos].charCodeAt() & 0x3F; // bit 5-0 + } else { + // old format header + tag = (input[mypos].charCodeAt() & 0x3F) >> 2; // bit 5-2 + packet_length_type = input[mypos].charCodeAt() & 0x03; // bit 1-0 + } + + // header octet parsing done + mypos++; + + // parsed length from length field + var len = 0; + var bodydata = null; + + // used for partial body lengths + var real_packet_length = -1; + if (!format) { + // 4.2.1. Old Format Packet Lengths + switch (packet_length_type) { + case 0: // The packet has a one-octet length. The header is 2 octets + // long. + packet_length = input[mypos++].charCodeAt(); + break; + case 1: // The packet has a two-octet length. The header is 3 octets + // long. + packet_length = (input[mypos++].charCodeAt() << 8) + | input[mypos++].charCodeAt(); + break; + case 2: // The packet has a four-octet length. The header is 5 + // octets long. + packet_length = (input[mypos++].charCodeAt() << 24) + | (input[mypos++].charCodeAt() << 16) + | (input[mypos++].charCodeAt() << 8) + | input[mypos++].charCodeAt(); + break; + default: + // 3 - The packet is of indeterminate length. The header is 1 + // octet long, and the implementation must determine how long + // the packet is. If the packet is in a file, this means that + // the packet extends until the end of the file. In general, + // an implementation SHOULD NOT use indeterminate-length + // packets except where the end of the data will be clear + // from the context, and even then it is better to use a + // definite length, or a new format header. The new format + // headers described below have a mechanism for precisely + // encoding data of indeterminate length. + } + + } else // 4.2.2. New Format Packet Lengths + { + + // 4.2.2.1. One-Octet Lengths + if (input[mypos].charCodeAt() < 192) { + packet_length = input[mypos++].charCodeAt(); + util.print_debug("1 byte length:" + packet_length); + // 4.2.2.2. Two-Octet Lengths + } else if (input[mypos].charCodeAt() >= 192 + && input[mypos].charCodeAt() < 224) { + packet_length = ((input[mypos++].charCodeAt() - 192) << 8) + + (input[mypos++].charCodeAt()) + 192; + util.print_debug("2 byte length:" + packet_length); + // 4.2.2.4. Partial Body Lengths + } else if (input[mypos].charCodeAt() > 223 + && input[mypos].charCodeAt() < 255) { + packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); + util.print_debug("4 byte length:" + packet_length); + // EEEK, we're reading the full data here... + var mypos2 = mypos + packet_length; + bodydata = input.substring(mypos, mypos + packet_length); + while (true) { + if (input[mypos2].charCodeAt() < 192) { + var tmplen = input[mypos2++].charCodeAt(); + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + break; + } else if (input[mypos2].charCodeAt() >= 192 + && input[mypos2].charCodeAt() < 224) { + var tmplen = ((input[mypos2++].charCodeAt() - 192) << 8) + + (input[mypos2++].charCodeAt()) + 192; + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + break; + } else if (input[mypos2].charCodeAt() > 223 + && input[mypos2].charCodeAt() < 255) { + var tmplen = 1 << (input[mypos2++].charCodeAt() & 0x1F); + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + } else { + mypos2++; + var tmplen = (input[mypos2++].charCodeAt() << 24) + | (input[mypos2++].charCodeAt() << 16) + | (input[mypos2++].charCodeAt() << 8) + | input[mypos2++].charCodeAt(); + bodydata += input.substring(mypos2, mypos2 + tmplen); + packet_length += tmplen; + mypos2 += tmplen; + break; + } + } + real_packet_length = mypos2; + // 4.2.2.3. Five-Octet Lengths + } else { + mypos++; + packet_length = (input[mypos++].charCodeAt() << 24) + | (input[mypos++].charCodeAt() << 16) + | (input[mypos++].charCodeAt() << 8) + | input[mypos++].charCodeAt(); + } + } + + // if there was'nt a partial body length: use the specified + // packet_length + if (real_packet_length == -1) { + real_packet_length = packet_length; + } + + if (bodydata == null) { + bodydata = input.substring(mypos, mypos + real_packet_length); + } + + // alert('tag type: '+this.tag+' length: '+packet_length); + var version = 1; // (old format; 2= new format) + // if (input[mypos++].charCodeAt() > 15) + // version = 2; + + switch (tag) { + case 0: // Reserved - a packet tag MUST NOT have this value + break; + case 1: // Public-Key Encrypted Session Key Packet + var result = new openpgp_packet_encryptedsessionkey(); + if (result.read_pub_key_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 2: // Signature Packet + var result = new openpgp_packet_signature(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 3: // Symmetric-Key Encrypted Session Key Packet + var result = new openpgp_packet_encryptedsessionkey(); + if (result.read_symmetric_key_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 4: // One-Pass Signature Packet + var result = new openpgp_packet_onepasssignature(); + if (result.read_packet(bodydata, 0, packet_length)) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 5: // Secret-Key Packet + var result = new openpgp_packet_keymaterial(); + result.header = input.substring(position, mypos); + if (result.read_tag5(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 6: // Public-Key Packet + var result = new openpgp_packet_keymaterial(); + result.header = input.substring(position, mypos); + if (result.read_tag6(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 7: // Secret-Subkey Packet + var result = new openpgp_packet_keymaterial(); + if (result.read_tag7(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 8: // Compressed Data Packet + var result = new openpgp_packet_compressed(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 9: // Symmetrically Encrypted Data Packet + var result = new openpgp_packet_encrypteddata(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 10: // Marker Packet = PGP (0x50, 0x47, 0x50) + var result = new openpgp_packet_marker(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 11: // Literal Data Packet + var result = new openpgp_packet_literaldata(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.header = input.substring(position, mypos); + result.packetLength = real_packet_length; + return result; + } + break; + case 12: // Trust Packet + // TODO: to be implemented + break; + case 13: // User ID Packet + var result = new openpgp_packet_userid(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 14: // Public-Subkey Packet + var result = new openpgp_packet_keymaterial(); + result.header = input.substring(position, mypos); + if (result.read_tag14(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 17: // User Attribute Packet + var result = new openpgp_packet_userattribute(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 18: // Sym. Encrypted and Integrity Protected Data Packet + var result = new openpgp_packet_encryptedintegrityprotecteddata(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + case 19: // Modification Detection Code Packet + var result = new openpgp_packet_modificationdetectioncode(); + if (result.read_packet(bodydata, 0, packet_length) != null) { + result.headerLength = mypos - position; + result.packetLength = real_packet_length; + return result; + } + break; + default: + util.print_error("openpgp.packet.js\n" + + "[ERROR] openpgp_packet: failed to parse packet @:" + + mypos + "\nchar:'" + + util.hexstrdump(input.substring(mypos)) + "'\ninput:" + + util.hexstrdump(input)); + return null; + break; + } + } + + this.read_packet = read_packet; +} + +var openpgp_packet = new _openpgp_packet(); +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the Compressed Data Packet (Tag 8) + * + * RFC4880 5.6: + * The Compressed Data packet contains compressed data. Typically, this + * packet is found as the contents of an encrypted packet, or following + * a Signature or One-Pass Signature packet, and contains a literal data + * packet. + */ +function openpgp_packet_compressed() { + this.tagType = 8; + + /** + * parsing function for the packet. + * @param input [string] payload of a tag 8 packet + * @param position [integer] position to start reading from the input string + * @param len [integer] length of the packet or the remaining length of input at position + * @return [openpgp_packet_compressed] object representation + */ + function read_packet (input, position, len) { + this.packetLength = len; + var mypos = position; + // One octet that gives the algorithm used to compress the packet. + this.type = input.charCodeAt(mypos++); + // Compressed data, which makes up the remainder of the packet. + this.compressedData = input.substring(position+1, position+len); + return this; + } + /** + * decompression method for decompressing the compressed data + * read by read_packet + * @return [String] the decompressed data + */ + function decompress() { + if (this.decompressedData != null) + return this.decompressedData; + + if (this.type == null) + return null; + + switch (this.type) { + case 0: // - Uncompressed + this.decompressedData = this.compressedData; + break; + case 1: // - ZIP [RFC1951] + var compData = this.compressedData; + var radix = s2r(compData).replace(/\n/g,""); + // no header in this case, directly call deflate + var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); + var outputString = unescape(jxg_obj.deflate()[0][0]); + var packet = openpgp_packet.read_packet(outputString, 0, outputString.length); + util.print_info('Decompressed packet [Type 1-ZIP]: ' + packet); + this.decompressedData = packet.data; + break; + case 2: // - ZLIB [RFC1950] + var compressionMethod = this.compressedData.charCodeAt(0) % 0x10; //RFC 1950. Bits 0-3 Compression Method + //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. + //2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary (how is this defined). Basic checksum, and compression level. + if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 + // remove 4 bytes ADLER32 checksum from the end + var compData = this.compressedData.substring(0, this.compressedData.length - 4); + var radix = s2r(compData).replace(/\n/g,""); + var outputString = JXG.decompress(radix); + //TODO check ADLER32 checksum + var packet = openpgp_packet.read_packet(outputString, 0, outputString.length); + util.print_info('Decompressed packet [Type 2-ZLIB]: ' + packet); + this.decompressedData = packet.data; + } else { + util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method."); + } + break; + case 3: // - BZip2 [BZ2] + // TODO: need to implement this + util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); + break; + default: + util.print_error("Compression algorithm unknown :"+this.type); + break; + } + util.print_debug("decompressed:"+util.hexstrdump(this.decompressedData)); + return this.decompressedData; + } + + /** + * Compress the packet data (member decompressedData) + * @param type [integer] algorithm to be used // See RFC 4880 9.3 + * @param data [String] data to be compressed + * @return [String] The compressed data stored in attribute compressedData + */ + function compress(type, data) { + this.type = type; + this.decompressedData = data; + switch (this.type) { + case 0: // - Uncompressed + this.compressedData = this.decompressedData; + break; + case 1: // - ZIP [RFC1951] + util.print_error("Compression algorithm ZIP [RFC1951] is not implemented."); + break; + case 2: // - ZLIB [RFC1950] + // TODO: need to implement this + util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented."); + break; + case 3: // - BZip2 [BZ2] + // TODO: need to implement this + util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); + break; + default: + util.print_error("Compression algorithm unknown :"+this.type); + break; + } + this.packetLength = this.compressedData.length +1; + return this.compressedData; + } + + /** + * creates a string representation of the packet + * @param algorithm [integer] algorithm to be used // See RFC 4880 9.3 + * @param data [String] data to be compressed + * @return [String] string-representation of the packet + */ + function write_packet(algorithm, data) { + this.decompressedData = data; + if (algorithm == null) { + this.type = 1; + } + var result = String.fromCharCode(this.type)+this.compress(this.type); + return openpgp_packet.write_packet_header(8, result.length)+result; + } + + /** + * pretty printing the packet (useful for debug purposes) + * @return [String] + */ + function toString() { + return '5.6. Compressed Data Packet (Tag 8)\n'+ + ' length: '+this.packetLength+'\n'+ + ' Compression Algorithm = '+this.type+'\n'+ + ' Compressed Data: Byte ['+util.hexstrdump(this.compressedData)+']\n'; + } + + this.read_packet = read_packet; + this.toString = toString; + this.compress = compress; + this.decompress = decompress; + this.write_packet = write_packet; +}; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + /** * Implementation of the Key Material Packet (Tag 5,6,7,14) * @@ -2457,7834 +3470,209 @@ function openpgp_packet_keymaterial() { this.write_private_key = write_private_key; this.write_public_key = write_public_key; } -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - /** - * Implementation of the strange "Marker packet" (Tag 10) - * - * RFC4880 5.8: An experimental version of PGP used this packet as the Literal - * packet, but no released version of PGP generated Literal packets with this - * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * - * Such a packet MUST be ignored when received. - */ -function openpgp_packet_marker() { - this.tagType = 10; - /** - * parsing function for a literal data packet (tag 10). - * - * @param input - * [string] payload of a tag 10 packet - * @param position - * [integer] position to start reading from the input string - * @param len - * [integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_packet(input, position, len) { - this.packetLength = 3; - if (input[position].charCodeAt() == 0x50 && // P - input[position + 1].charCodeAt() == 0x47 && // G - input[position + 2].charCodeAt() == 0x50) // P - return this; - // marker packet does not contain "PGP" - return null; - } - - /** - * Generates Debug output - * - * @return String which gives some information about the keymaterial - */ - function toString() { - return "5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)\n" - + " packet reads: \"PGP\"\n"; - } - - this.read_packet = read_packet; - this.toString = toString; -}// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the Modification Detection Code Packet (Tag 19) - * - * RFC4880 5.14: The Modification Detection Code packet contains a SHA-1 hash of - * plaintext data, which is used to detect message modification. It is only used - * with a Symmetrically Encrypted Integrity Protected Data packet. The - * Modification Detection Code packet MUST be the last packet in the plaintext - * data that is encrypted in the Symmetrically Encrypted Integrity Protected - * Data packet, and MUST appear in no other place. - */ - -function openpgp_packet_modificationdetectioncode() { - this.tagType = 19; - this.hash = null; - /** - * parsing function for a modification detection code packet (tag 19). - * - * @param input - * [String] payload of a tag 19 packet - * @param position - * [Integer] position to start reading from the input string - * @param len - * [Integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_packet(input, position, len) { - this.packetLength = len; - - if (len != 20) { - util - .print_error("openpgp.packet.modificationdetectioncode.js\n" - + 'invalid length for a modification detection code packet!' - + len); - return null; - } - // - A 20-octet SHA-1 hash of the preceding plaintext data of the - // Symmetrically Encrypted Integrity Protected Data packet, - // including prefix data, the tag octet, and length octet of the - // Modification Detection Code packet. - this.hash = input.substring(position, position + 20); - return this; - } - - /* - * this packet is created within the encryptedintegrityprotected packet - * function write_packet(data) { } - */ - - /** - * generates debug output (pretty print) - * - * @return String which gives some information about the modification - * detection code - */ - function toString() { - return '5.14 Modification detection code packet\n' + ' bytes (' - + this.hash.length + '): [' + util.hexstrdump(this.hash) + ']'; - } - this.read_packet = read_packet; - this.toString = toString; -}; -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -function _openpgp_packet() { - /** - * Encodes a given integer of length to the openpgp length specifier to a - * string - * - * @param length - * [Integer] of the length to encode - * @return string with openpgp length representation - */ - function encode_length(length) { - result = ""; - if (length < 192) { - result += String.fromCharCode(length); - } else if (length > 191 && length < 8384) { - /* - * let a = (total data packet length) - 192 let bc = two octet - * representation of a let d = b + 192 - */ - result += String.fromCharCode(((length - 192) >> 8) + 192); - result += String.fromCharCode((length - 192) & 0xFF); - } else { - result += String.fromCharCode(255); - result += String.fromCharCode((length >> 24) & 0xFF); - result += String.fromCharCode((length >> 16) & 0xFF); - result += String.fromCharCode((length >> 8) & 0xFF); - result += String.fromCharCode(length & 0xFF); - } - return result; - } - this.encode_length = encode_length; - - /** - * Writes a packet header version 4 with the given tag_type and length to a - * string - * - * @param tag_type - * integer of tag type - * @param length - * integer length of the payload - * @return string of the header - */ - function write_packet_header(tag_type, length) { - /* we're only generating v4 packet headers here */ - var result = ""; - result += String.fromCharCode(0xC0 | tag_type); - result += encode_length(length); - return result; - } - - /** - * Writes a packet header Version 3 with the given tag_type and length to a - * string - * - * @param tag_type - * integer of tag type - * @param length - * integer length of the payload - * @return string of the header - */ - function write_old_packet_header(tag_type, length) { - var result = ""; - if (length < 256) { - result += String.fromCharCode(0x80 | (tag_type << 2)); - result += String.fromCharCode(length); - } else if (length < 65536) { - result += String.fromCharCode(0x80 | (tag_type << 2) | 1); - result += String.fromCharCode(length >> 8); - result += String.fromCharCode(length & 0xFF); - } else { - result += String.fromCharCode(0x80 | (tag_type << 2) | 2); - result += String.fromCharCode((length >> 24) & 0xFF); - result += String.fromCharCode((length >> 16) & 0xFF); - result += String.fromCharCode((length >> 8) & 0xFF); - result += String.fromCharCode(length & 0xFF); - } - return result; - } - this.write_old_packet_header = write_old_packet_header; - this.write_packet_header = write_packet_header; - /** - * Generic static Packet Parser function - * - * @param input - * [String] input stream as string - * @param position - * [integer] position to start parsing - * @param len - * [integer] length of the input from position on - * @return [openpgp_packet_*] returns a parsed openpgp_packet - */ - function read_packet(input, position, len) { - // some sanity checks - if (input == null || input.length <= position - || input.substring(position).length < 2 - || (input[position].charCodeAt() & 0x80) == 0) { - util - .print_error("Error during parsing. This message / key is propably not containing a valid OpenPGP format."); - return null; - } - var mypos = position; - var tag = -1; - var format = -1; - - format = 0; // 0 = old format; 1 = new format - if ((input[mypos].charCodeAt() & 0x40) != 0) { - format = 1; - } - - var packet_length_type; - if (format) { - // new format header - tag = input[mypos].charCodeAt() & 0x3F; // bit 5-0 - } else { - // old format header - tag = (input[mypos].charCodeAt() & 0x3F) >> 2; // bit 5-2 - packet_length_type = input[mypos].charCodeAt() & 0x03; // bit 1-0 - } - - // header octet parsing done - mypos++; - - // parsed length from length field - var len = 0; - var bodydata = null; - - // used for partial body lengths - var real_packet_length = -1; - if (!format) { - // 4.2.1. Old Format Packet Lengths - switch (packet_length_type) { - case 0: // The packet has a one-octet length. The header is 2 octets - // long. - packet_length = input[mypos++].charCodeAt(); - break; - case 1: // The packet has a two-octet length. The header is 3 octets - // long. - packet_length = (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - break; - case 2: // The packet has a four-octet length. The header is 5 - // octets long. - packet_length = (input[mypos++].charCodeAt() << 24) - | (input[mypos++].charCodeAt() << 16) - | (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - break; - default: - // 3 - The packet is of indeterminate length. The header is 1 - // octet long, and the implementation must determine how long - // the packet is. If the packet is in a file, this means that - // the packet extends until the end of the file. In general, - // an implementation SHOULD NOT use indeterminate-length - // packets except where the end of the data will be clear - // from the context, and even then it is better to use a - // definite length, or a new format header. The new format - // headers described below have a mechanism for precisely - // encoding data of indeterminate length. - } - - } else // 4.2.2. New Format Packet Lengths - { - - // 4.2.2.1. One-Octet Lengths - if (input[mypos].charCodeAt() < 192) { - packet_length = input[mypos++].charCodeAt(); - util.print_debug("1 byte length:" + packet_length); - // 4.2.2.2. Two-Octet Lengths - } else if (input[mypos].charCodeAt() >= 192 - && input[mypos].charCodeAt() < 224) { - packet_length = ((input[mypos++].charCodeAt() - 192) << 8) - + (input[mypos++].charCodeAt()) + 192; - util.print_debug("2 byte length:" + packet_length); - // 4.2.2.4. Partial Body Lengths - } else if (input[mypos].charCodeAt() > 223 - && input[mypos].charCodeAt() < 255) { - packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); - util.print_debug("4 byte length:" + packet_length); - // EEEK, we're reading the full data here... - var mypos2 = mypos + packet_length; - bodydata = input.substring(mypos, mypos + packet_length); - while (true) { - if (input[mypos2].charCodeAt() < 192) { - var tmplen = input[mypos2++].charCodeAt(); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input[mypos2].charCodeAt() >= 192 - && input[mypos2].charCodeAt() < 224) { - var tmplen = ((input[mypos2++].charCodeAt() - 192) << 8) - + (input[mypos2++].charCodeAt()) + 192; - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input[mypos2].charCodeAt() > 223 - && input[mypos2].charCodeAt() < 255) { - var tmplen = 1 << (input[mypos2++].charCodeAt() & 0x1F); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - } else { - mypos2++; - var tmplen = (input[mypos2++].charCodeAt() << 24) - | (input[mypos2++].charCodeAt() << 16) - | (input[mypos2++].charCodeAt() << 8) - | input[mypos2++].charCodeAt(); - bodydata += input.substring(mypos2, mypos2 + tmplen); - packet_length += tmplen; - mypos2 += tmplen; - break; - } - } - real_packet_length = mypos2; - // 4.2.2.3. Five-Octet Lengths - } else { - mypos++; - packet_length = (input[mypos++].charCodeAt() << 24) - | (input[mypos++].charCodeAt() << 16) - | (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - } - } - - // if there was'nt a partial body length: use the specified - // packet_length - if (real_packet_length == -1) { - real_packet_length = packet_length; - } - - if (bodydata == null) { - bodydata = input.substring(mypos, mypos + real_packet_length); - } - - // alert('tag type: '+this.tag+' length: '+packet_length); - var version = 1; // (old format; 2= new format) - // if (input[mypos++].charCodeAt() > 15) - // version = 2; - - switch (tag) { - case 0: // Reserved - a packet tag MUST NOT have this value - break; - case 1: // Public-Key Encrypted Session Key Packet - var result = new openpgp_packet_encryptedsessionkey(); - if (result.read_pub_key_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 2: // Signature Packet - var result = new openpgp_packet_signature(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 3: // Symmetric-Key Encrypted Session Key Packet - var result = new openpgp_packet_encryptedsessionkey(); - if (result.read_symmetric_key_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 4: // One-Pass Signature Packet - var result = new openpgp_packet_onepasssignature(); - if (result.read_packet(bodydata, 0, packet_length)) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 5: // Secret-Key Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag5(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 6: // Public-Key Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag6(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 7: // Secret-Subkey Packet - var result = new openpgp_packet_keymaterial(); - if (result.read_tag7(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 8: // Compressed Data Packet - var result = new openpgp_packet_compressed(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 9: // Symmetrically Encrypted Data Packet - var result = new openpgp_packet_encrypteddata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 10: // Marker Packet = PGP (0x50, 0x47, 0x50) - var result = new openpgp_packet_marker(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 11: // Literal Data Packet - var result = new openpgp_packet_literaldata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.header = input.substring(position, mypos); - result.packetLength = real_packet_length; - return result; - } - break; - case 12: // Trust Packet - // TODO: to be implemented - break; - case 13: // User ID Packet - var result = new openpgp_packet_userid(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 14: // Public-Subkey Packet - var result = new openpgp_packet_keymaterial(); - result.header = input.substring(position, mypos); - if (result.read_tag14(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 17: // User Attribute Packet - var result = new openpgp_packet_userattribute(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 18: // Sym. Encrypted and Integrity Protected Data Packet - var result = new openpgp_packet_encryptedintegrityprotecteddata(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - case 19: // Modification Detection Code Packet - var result = new openpgp_packet_modificationdetectioncode(); - if (result.read_packet(bodydata, 0, packet_length) != null) { - result.headerLength = mypos - position; - result.packetLength = real_packet_length; - return result; - } - break; - default: - util.print_error("openpgp.packet.js\n" - + "[ERROR] openpgp_packet: failed to parse packet @:" - + mypos + "\nchar:'" - + util.hexstrdump(input.substring(mypos)) + "'\ninput:" - + util.hexstrdump(input)); - return null; - break; - } - } - - this.read_packet = read_packet; -} - -var openpgp_packet = new _openpgp_packet(); -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. - */ -function openpgp_packet_literaldata() { - this.tagType = 11; - - /** - * parsing function for a literal data packet (tag 11). - * - * @param input - * [string] payload of a tag 11 packet - * @param position - * [integer] position to start reading from the input string - * @param len - * [integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_packet(input, position, len) { - this.packetLength = len; - // - A one-octet field that describes how the data is formatted. - - this.format = input[position]; - this.filename = input.substr(position + 2, input - .charCodeAt(position + 1)); - this.date = new Date(parseInt(input.substr(position + 2 - + input.charCodeAt(position + 1), 4)) * 1000); - this.data = input.substring(position + 6 - + input.charCodeAt(position + 1)); - return this; - } - - /** - * Creates a string representation of the packet - * - * @param data - * [String] the data to be inserted as body - * @return [String] string-representation of the packet - */ - function write_packet(data) { - data = data.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"); - this.filename = "msg.txt"; - this.date = new Date(); - this.format = 't'; - var result = openpgp_packet.write_packet_header(11, data.length + 6 - + this.filename.length); - result += this.format; - result += String.fromCharCode(this.filename.length); - result += this.filename; - result += String - .fromCharCode((Math.round(this.date.getTime() / 1000) >> 24) & 0xFF); - result += String - .fromCharCode((Math.round(this.date.getTime() / 1000) >> 16) & 0xFF); - result += String - .fromCharCode((Math.round(this.date.getTime() / 1000) >> 8) & 0xFF); - result += String - .fromCharCode(Math.round(this.date.getTime() / 1000) & 0xFF); - result += data; - this.data = data; - return result; - } - - /** - * generates debug output (pretty print) - * - * @return String which gives some information about the keymaterial - */ - function toString() { - return '5.9. Literal Data Packet (Tag 11)\n' + ' length: ' - + this.packetLength + '\n' + ' format: ' + this.format - + '\n' + ' filename:' + this.filename + '\n' - + ' date: ' + this.date + '\n' + ' data: |' - + this.data + '|\n' + ' rdata: |' + this.real_data + '|\n'; - } - - this.read_packet = read_packet; - this.toString = toString; - this.write_packet = write_packet; -} -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. - */ -function openpgp_packet_compressed() { - this.tagType = 8; - - /** - * parsing function for the packet. - * @param input [string] payload of a tag 8 packet - * @param position [integer] position to start reading from the input string - * @param len [integer] length of the packet or the remaining length of input at position - * @return [openpgp_packet_compressed] object representation - */ - function read_packet (input, position, len) { - this.packetLength = len; - var mypos = position; - // One octet that gives the algorithm used to compress the packet. - this.type = input.charCodeAt(mypos++); - // Compressed data, which makes up the remainder of the packet. - this.compressedData = input.substring(position+1, position+len); - return this; - } - /** - * decompression method for decompressing the compressed data - * read by read_packet - * @return [String] the decompressed data - */ - function decompress() { - if (this.decompressedData != null) - return this.decompressedData; - - if (this.type == null) - return null; - - switch (this.type) { - case 0: // - Uncompressed - this.decompressedData = this.compressedData; - break; - case 1: // - ZIP [RFC1951] - var compData = this.compressedData; - var radix = s2r(compData).replace(/\n/g,""); - // no header in this case, directly call deflate - var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); - var outputString = unescape(jxg_obj.deflate()[0][0]); - var packet = openpgp_packet.read_packet(outputString, 0, outputString.length); - util.print_info('Decompressed packet [Type 1-ZIP]: ' + packet); - this.decompressedData = packet.data; - break; - case 2: // - ZLIB [RFC1950] - var compressionMethod = this.compressedData.charCodeAt(0) % 0x10; //RFC 1950. Bits 0-3 Compression Method - //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. - //2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary (how is this defined). Basic checksum, and compression level. - if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 - // remove 4 bytes ADLER32 checksum from the end - var compData = this.compressedData.substring(0, this.compressedData.length - 4); - var radix = s2r(compData).replace(/\n/g,""); - var outputString = JXG.decompress(radix); - //TODO check ADLER32 checksum - var packet = openpgp_packet.read_packet(outputString, 0, outputString.length); - util.print_info('Decompressed packet [Type 2-ZLIB]: ' + packet); - this.decompressedData = packet.data; - } else { - util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method."); - } - break; - case 3: // - BZip2 [BZ2] - // TODO: need to implement this - util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); - break; - default: - util.print_error("Compression algorithm unknown :"+this.type); - break; - } - util.print_debug("decompressed:"+util.hexstrdump(this.decompressedData)); - return this.decompressedData; - } - - /** - * Compress the packet data (member decompressedData) - * @param type [integer] algorithm to be used // See RFC 4880 9.3 - * @param data [String] data to be compressed - * @return [String] The compressed data stored in attribute compressedData - */ - function compress(type, data) { - this.type = type; - this.decompressedData = data; - switch (this.type) { - case 0: // - Uncompressed - this.compressedData = this.decompressedData; - break; - case 1: // - ZIP [RFC1951] - util.print_error("Compression algorithm ZIP [RFC1951] is not implemented."); - break; - case 2: // - ZLIB [RFC1950] - // TODO: need to implement this - util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented."); - break; - case 3: // - BZip2 [BZ2] - // TODO: need to implement this - util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); - break; - default: - util.print_error("Compression algorithm unknown :"+this.type); - break; - } - this.packetLength = this.compressedData.length +1; - return this.compressedData; - } - - /** - * creates a string representation of the packet - * @param algorithm [integer] algorithm to be used // See RFC 4880 9.3 - * @param data [String] data to be compressed - * @return [String] string-representation of the packet - */ - function write_packet(algorithm, data) { - this.decompressedData = data; - if (algorithm == null) { - this.type = 1; - } - var result = String.fromCharCode(this.type)+this.compress(this.type); - return openpgp_packet.write_packet_header(8, result.length)+result; - } - - /** - * pretty printing the packet (useful for debug purposes) - * @return [String] - */ - function toString() { - return '5.6. Compressed Data Packet (Tag 8)\n'+ - ' length: '+this.packetLength+'\n'+ - ' Compression Algorithm = '+this.type+'\n'+ - ' Compressed Data: Byte ['+util.hexstrdump(this.compressedData)+']\n'; - } - - this.read_packet = read_packet; - this.toString = toString; - this.compress = compress; - this.decompress = decompress; - this.write_packet = write_packet; -}; -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * A User ID packet consists of UTF-8 text that is intended to represent - * the name and email address of the key holder. By convention, it - * includes an RFC 2822 [RFC2822] mail name-addr, but there are no - * restrictions on its content. The packet length in the header - * specifies the length of the User ID. - */ - -function openpgp_packet_userid() { - this.tagType = 13; - this.certificationSignatures = new Array(); - this.certificationRevocationSignatures = new Array(); - this.revocationSignatures = new Array(); - this.parentNode = null; - - /** - * parsing function for a user id packet (tag 13). - * @param input [string] payload of a tag 13 packet - * @param position [integer] position to start reading from the input string - * @param len [integer] length of the packet or the remaining length of input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_packet(input, position, len) { - this.text = ''; - this.packetLength = len; - - for ( var i = 0; i < len; i++) { - this.text += input[position + i]; - } - return this; - } - - /** - * creates a string representation of the user id packet - * @param user_id [String] the user id as string ("John Doe 15 - && result.signatureType < 20) { // certification - // // - // signature - this.certificationSignatures[this.certificationSignatures.length] = result; - break; - } else if (result.signatureType == 48) {// certification revocation signature - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - break; - } else if (result.signatureType == 24) { // omg. standalone signature - this.certificationSignatures[this.certificationSignatures.length] = result; - break; - } else { - util.debug("unknown sig t: "+result.signatureType+"@"+(pos - (result.packetLength + result.headerLength))); - } - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } - } - } - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } else if (parent_node.tagType == 5) { // secret Key - this.parentNode = parent_node; - var exit = false; - var pos = position; - while (input.length != pos) { - var result = openpgp_packet.read_packet(input, pos, l - (pos - position)); - if (result == null) { - util.print_error('parsing ends here @:' + pos + " l:" + l); - break; - } else { - pos += result.packetLength + result.headerLength; - l = input.length - pos; - switch (result.tagType) { - case 2: // Signature Packet certification signature - if (result.signatureType > 15 - && result.signatureType < 20) - this.certificationSignatures[this.certificationSignatures.length] = result; - // certification revocation signature - else if (result.signatureType == 48) - this.certificationRevocationSignatures[this.certificationRevocationSignatures.length] = result; - default: - this.data = input; - this.position = position - parent_node.packetLength; - this.len = pos - position -(result.headerLength + result.packetLength); - return this.len; - } - } - } - } else { - util.print_error("unknown parent node for a userId packet "+parent_node.tagType); - } - } - - /** - * generates debug output (pretty print) - * @return String which gives some information about the user id packet - */ - function toString() { - var result = ' 5.11. User ID Packet (Tag 13)\n' + ' text (' - + this.text.length + '): "' + this.text.replace("<", "<") - + '"\n'; - result +="certification signatures:\n"; - for (var i = 0; i < this.certificationSignatures.length; i++) { - result += " "+this.certificationSignatures[i].toString(); - } - result +="certification revocation signatures:\n"; - for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { - result += " "+this.certificationRevocationSignatures[i].toString(); - } - return result; - } - - /** - * lookup function to find certification revocation signatures - * @param keyId string containing the key id of the issuer of this signature - * @return a CertificationRevocationSignature if found; otherwise null - */ - function hasCertificationRevocationSignature(keyId) { - for (var i = 0; i < this.certificationRevocationSignatures.length; i++) { - if ((this.certificationRevocationSignatures[i].version == 3 && - this.certificationRevocationSignatures[i].keyId == keyId) || - (this.certificationRevocationSignatures[i].version == 4 && - this.certificationRevocationSignatures[i].issuerKeyId == keyId)) - return this.certificationRevocationSignatures[i]; - } - return null; - } - - /** - * Verifies all certification signatures. This method does not consider possible revocation signatures. - * @param publicKeyPacket the top level key material - * @return an array of integers corresponding to the array of certification signatures. The meaning of each integer is the following: - * 0 = bad signature - * 1 = signature expired - * 2 = issuer key not available - * 3 = revoked - * 4 = signature valid - * 5 = signature by key owner expired - * 6 = signature by key owner revoked - */ - function verifyCertificationSignatures(publicKeyPacket) { - result = new Array(); - for (var i = 0 ; i < this.certificationSignatures.length; i++) { - // A certification signature (type 0x10 through 0x13) hashes the User - // ID being bound to the key into the hash context after the above - // data. A V3 certification hashes the contents of the User ID or - // attribute packet packet, without any header. A V4 certification - // hashes the constant 0xB4 for User ID certifications or the constant - // 0xD1 for User Attribute certifications, followed by a four-octet - // number giving the length of the User ID or User Attribute data, and - // then the User ID or User Attribute data. - - if (this.certificationSignatures[i].version == 4) { - if (this.certificationSignatures[i].signatureExpirationTime != null && - this.certificationSignatures[i].signatureExpirationTime != null && - this.certificationSignatures[i].signatureExpirationTime != 0 && - !this.certificationSignatures[i].signatureNeverExpires && - new Date(this.certificationSignatures[i].creationTime.getTime() +(this.certificationSignatures[i].signatureExpirationTime*1000)) < new Date()) { - if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) - result[i] = 5; - else - result[i] = 1; - continue; - } - if (this.certificationSignatures[i].issuerKeyId == null) { - result[i] = 0; - continue; - } - var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].issuerKeyId); - if (issuerPublicKey == null || issuerPublicKey.length == 0) { - result[i] = 2; - continue; - } - // TODO: try to verify all returned issuer public keys (key ids are not unique!) - var issuerPublicKey = issuerPublicKey[0]; - var signingKey = issuerPublicKey.obj.getSigningKey(); - if (signingKey == null) { - result[i] = 0; - continue; - } - var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].issuerKeyId); - if (revocation != null && revocation.creationTime > - this.certificationSignatures[i].creationTime) { - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data+String.fromCharCode(0xB4)+ - String.fromCharCode((this.text.length >> 24) & 0xFF)+ - String.fromCharCode((this.text.length >> 16) & 0xFF)+ - String.fromCharCode((this.text.length >> 8) & 0xFF)+ - String.fromCharCode((this.text.length) & 0xFF)+ - this.text; - if (revocation.verify(signaturedata, signingKey)) { - if (this.certificationSignatures[i].issuerKeyId == publicKeyPacket.getKeyId()) - result[i] = 6; - else - result[i] = 3; - continue; - } - } - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data+String.fromCharCode(0xB4)+ - String.fromCharCode((this.text.length >> 24) & 0xFF)+ - String.fromCharCode((this.text.length >> 16) & 0xFF)+ - String.fromCharCode((this.text.length >> 8) & 0xFF)+ - String.fromCharCode((this.text.length) & 0xFF)+ - this.text; - if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { - result[i] = 4; - } else - result[i] = 0; - } else if (this.certificationSignatures[i].version == 3) { - if (this.certificationSignatures[i].keyId == null) { - result[i] = 0; - continue; - } - var issuerPublicKey = openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[i].keyId); - if (issuerPublicKey == null || issuerPublicKey.length == 0) { - result[i] = 2; - continue; - } - issuerPublicKey = issuerPublicKey[0]; - var signingKey = publicKey.obj.getSigningKey(); - if (signingKey == null) { - result[i] = 0; - continue; - } - var revocation = this.hasCertificationRevocationSignature(this.certificationSignatures[i].keyId); - if (revocation != null && revocation.creationTime > - this.certificationSignatures[i].creationTime) { - var signaturedata = String.fromCharCode(0x99)+ this.publicKeyPacket.header.substring(1)+ - this.publicKeyPacket.data+this.text; - if (revocation.verify(signaturedata, signingKey)) { - if (revocation.keyId == publicKeyPacket.getKeyId()) - result[i] = 6; - else - result[i] = 3; - continue; - } - } - var signaturedata = String.fromCharCode(0x99)+ publicKeyPacket.header.substring(1)+ - publicKeyPacket.data+this.text; - if (this.certificationSignatures[i].verify(signaturedata, signingKey)) { - result[i] = 4; - } else - result[i] = 0; - } else { - result[i] = 0; - } - } - return result; - } - - /** - * verifies the signatures of the user id - * @return 0 if the userid is valid; 1 = userid expired; 2 = userid revoked - */ - function verify(publicKeyPacket) { - var result = this.verifyCertificationSignatures(publicKeyPacket); - if (result.indexOf(6) != -1) - return 2; - if (result.indexOf(5) != -1) - return 1; - return 0; - } - - // TODO: implementation missing - function addCertification(publicKeyPacket, privateKeyPacket) { - - } - - // TODO: implementation missing - function revokeCertification(publicKeyPacket, privateKeyPacket) { - - } - - this.hasCertificationRevocationSignature = hasCertificationRevocationSignature; - this.verifyCertificationSignatures = verifyCertificationSignatures; - this.verify = verify; - this.read_packet = read_packet; - this.write_packet = write_packet; - this.toString = toString; - this.read_nodes = read_nodes; -} -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the Sym. Encrypted Integrity Protected Data Packet (Tag 18) - * - * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is - * a variant of the Symmetrically Encrypted Data packet. It is a new feature - * created for OpenPGP that addresses the problem of detecting a modification to - * encrypted data. It is used in combination with a Modification Detection Code - * packet. - */ - -function openpgp_packet_encryptedintegrityprotecteddata() { - this.tagType = 18; - this.version = null; // integer == 1 - this.packetLength = null; // integer - this.encryptedData = null; // string - this.decrytpedData = null; // string - this.hash = null; // string - /** - * parsing function for the packet. - * - * @param input - * [string] payload of a tag 18 packet - * @param position - * [integer] position to start reading from the input string - * @param len - * [integer] length of the packet or the remaining length of - * input at position - * @return [openpgp_packet_encryptedintegrityprotecteddata] object - * representation - */ - function read_packet(input, position, len) { - this.packetLength = len; - // - A one-octet version number. The only currently defined value is - // 1. - this.version = input[position].charCodeAt(); - if (this.version != 1) { - util - .print_error('openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: ' - + this.version - + " , @ " - + position - + "hex:" - + util.hexstrdump(input)); - return null; - } - // - Encrypted data, the output of the selected symmetric-key cipher - // operating in Cipher Feedback mode with shift amount equal to the - // block size of the cipher (CFB-n where n is the block size). - this.encryptedData = input.substring(position + 1, position + 1 + len); - util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n" - + this.toString()); - return this; - } - - /** - * Creates a string representation of a Sym. Encrypted Integrity Protected - * Data Packet (tag 18) (see RFC4880 5.13) - * - * @param symmetric_algorithm - * [integer] the selected symmetric encryption algorithm to be - * used - * @param key - * [String] the key of cipher blocksize length to be used - * @param data - * plaintext data to be encrypted within the packet - * @return a string representation of the packet - */ - function write_packet(symmetric_algorithm, key, data) { - - var prefixrandom = openpgp_crypto_getPrefixRandom(symmetric_algorithm); - var prefix = prefixrandom - + prefixrandom.charAt(prefixrandom.length - 2) - + prefixrandom.charAt(prefixrandom.length - 1); - var tohash = data; - tohash += String.fromCharCode(0xD3); - tohash += String.fromCharCode(0x14); - util.print_debug_hexstr_dump("data to be hashed:" - , prefix + tohash); - tohash += str_sha1(prefix + tohash); - util.print_debug_hexstr_dump("hash:" - , tohash.substring(tohash.length - 20, - tohash.length)); - var result = openpgp_crypto_symmetricEncrypt(prefixrandom, - symmetric_algorithm, key, tohash, false).substring(0, - prefix.length + tohash.length); - var header = openpgp_packet.write_packet_header(18, result.length + 1) - + String.fromCharCode(1); - this.encryptedData = result; - return header + result; - } - - /** - * Decrypts the encrypted data contained in this object read_packet must - * have been called before - * - * @param symmetric_algorithm_type - * [integer] the selected symmetric encryption algorithm to be - * used - * @param key - * [String] the key of cipher blocksize length to be used - * @return the decrypted data of this packet - */ - function decrypt(symmetric_algorithm_type, key) { - this.decryptedData = openpgp_crypto_symmetricDecrypt( - symmetric_algorithm_type, key, this.encryptedData, false); - // there must be a modification detection code packet as the - // last packet and everything gets hashed except the hash itself - this.hash = str_sha1(openpgp_crypto_MDCSystemBytes( - symmetric_algorithm_type, key, this.encryptedData) - + this.decryptedData.substring(0, - this.decryptedData.length - 20)); - util.print_debug_hexstr_dump("calc hash = ", this.hash); - if (this.hash == this.decryptedData.substring( - this.decryptedData.length - 20, this.decryptedData.length)) - return this.decryptedData; - else - util - .print_error("Decryption stopped: discovered a modification of encrypted data."); - return null; - } - - function toString() { - var data = ''; - if(openpgp.config.debug) - data = ' data: Bytes [' - + util.hexstrdump(this.encryptedData) + ']'; - - return '5.13. Sym. Encrypted Integrity Protected Data Packet (Tag 18)\n' - + ' length: ' - + this.packetLength - + '\n' - + ' version: ' - + this.version - + '\n' - + data; - } - - this.write_packet = write_packet; - this.read_packet = read_packet; - this.toString = toString; - this.decrypt = decrypt; -}; -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the One-Pass Signature Packets (Tag 4) - * - * RFC4880 5.4: - * The One-Pass Signature packet precedes the signed data and contains - * enough information to allow the receiver to begin calculating any - * hashes needed to verify the signature. It allows the Signature - * packet to be placed at the end of the message, so that the signer - * can compute the entire signed message in one pass. - */ -function openpgp_packet_onepasssignature() { - this.tagType = 4; - this.version = null; // A one-octet version number. The current version is 3. - this.type == null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. - this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) - this.publicKeyAlgorithm = null; // A one-octet number describing the public-key algorithm used. (See RFC4880 9.1) - this.signingKeyId = null; // An eight-octet number holding the Key ID of the signing key. - this.flags = null; // A one-octet number holding a flag showing whether the signature is nested. A zero value indicates that the next packet is another One-Pass Signature packet that describes another signature to be applied to the same message data. - - /** - * parsing function for a one-pass signature packet (tag 4). - * @param input [string] payload of a tag 4 packet - * @param position [integer] position to start reading from the input string - * @param len [integer] length of the packet or the remaining length of input at position - * @return [openpgp_packet_encrypteddata] object representation - */ - function read_packet(input, position, len) { - this.packetLength = len; - var mypos = position; - // A one-octet version number. The current version is 3. - this.version = input.charCodeAt(mypos++); - - // A one-octet signature type. Signature types are described in - // Section 5.2.1. - this.type = input.charCodeAt(mypos++); - - // A one-octet number describing the hash algorithm used. - this.hashAlgorithm = input.charCodeAt(mypos++); - - // A one-octet number describing the public-key algorithm used. - this.publicKeyAlgorithm = input.charCodeAt(mypos++); - // An eight-octet number holding the Key ID of the signing key. - this.signingKeyId = new openpgp_type_keyid(); - this.signingKeyId.read_packet(input,mypos); - mypos += 8; - - // A one-octet number holding a flag showing whether the signature - // is nested. A zero value indicates that the next packet is - // another One-Pass Signature packet that describes another - // signature to be applied to the same message data. - this.flags = input.charCodeAt(mypos++); - return this; - } - - /** - * creates a string representation of a one-pass signature packet - * @param type [integer] Signature types as described in RFC4880 Section 5.2.1. - * @param hashalgorithm [integer] the hash algorithm used within the signature - * @param privatekey [openpgp_msg_privatekey] the private key used to generate the signature - * @param length [integer] length of data to be signed - * @param nested [boolean] boolean showing whether the signature is nested. - * "true" indicates that the next packet is another One-Pass Signature packet - * that describes another signature to be applied to the same message data. - * @return [String] a string representation of a one-pass signature packet - */ - function write_packet(type, hashalgorithm, privatekey,length, nested) { - var result =""; - - result += openpgp_packet.write_packet_header(4,13); - result += String.fromCharCode(3); - result += String.fromCharCode(type); - result += String.fromCharCode(hashalgorithm); - result += String.fromCharCode(privatekey.privateKeyPacket.publicKey.publicKeyAlgorithm); - result += privatekey.getKeyId(); - if (nested) - result += String.fromCharCode(0); - else - result += String.fromCharCode(1); - - return result; - } - - /** - * generates debug output (pretty print) - * @return String which gives some information about the one-pass signature packet - */ - function toString() { - return '5.4. One-Pass Signature Packets (Tag 4)\n'+ - ' length: '+this.packetLength+'\n'+ - ' type: '+this.type+'\n'+ - ' keyID: '+this.signingKeyId.toString()+'\n'+ - ' hashA: '+this.hashAlgorithm+'\n'+ - ' pubKeyA:'+this.publicKeyAlgorithm+'\n'+ - ' flags: '+this.flags+'\n'+ - ' version:'+this.version+'\n'; - } - - this.read_packet = read_packet; - this.toString = toString; - this.write_packet = write_packet; -};// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the GPG4Browsers config object + * A fast MD5 JavaScript implementation + * Copyright (c) 2012 Joseph Myers + * http://www.myersdaily.org/joseph/javascript/md5-text.html * - * This object contains configuration values and implements - * storing and retrieving configuration them from HTML5 local storage. + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purposes and without + * fee is hereby granted provided that this copyright notice + * appears in all copies. * - * This object can be accessed after calling openpgp.init() - * using openpgp.config - * Stored config parameters can be accessed using - * openpgp.config.config - */ -function openpgp_config() { - this.config = null; - - /** - * the default config object which is used if no - * configuration was in place - */ - this.default_config = { - prefer_hash_algorithm: 2, - encryption_cipher: 9, - compression: 1, - show_version: true, - show_comment: true, - integrity_protect: true, - composition_behavior: 0, - keyserver: "keyserver.linux.it" // "pgp.mit.edu:11371" - }; - - this.versionstring ="OpenPGP.js v.1.20120904"; - this.commentstring ="http://openpgpjs.org"; - /** - * reads the config out of the HTML5 local storage - * and initializes the object config. - * if config is null the default config will be used - * @return [void] - */ - function read() { - var cf = JSON.parse(window.localStorage.getItem("config")); - if (cf == null) { - this.config = this.default_config; - this.write(); - } - else - this.config = cf; - } - - /** - * if enabled, debug messages will be printed - */ - this.debug = false; - - /** - * writes the config to HTML5 local storage - * @return [void] - */ - function write() { - window.localStorage.setItem("config",JSON.stringify(this.config)); - } - - this.read = read; - this.write = write; -} -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of the String-to-key specifier (RFC4880 3.7) - * String-to-key (S2K) specifiers are used to convert passphrase strings - into symmetric-key encryption/decryption keys. They are used in two - places, currently: to encrypt the secret part of private keys in the - private keyring, and to convert passphrases to encryption keys for - symmetrically encrypted messages. - */ -function openpgp_type_s2k() { - /** - * parsing function for a string-to-key specifier (RFC 4880 3.7). - * @param input [string] payload of string-to-key specifier - * @param position [integer] position to start reading from the input string - * @return [openpgp_type_s2k] object representation - */ - function read(input, position) { - var mypos = position; - this.type = input[mypos++].charCodeAt(); - switch (this.type) { - case 0: // Simple S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input[mypos++].charCodeAt(); - this.s2kLength = 1; - break; - - case 1: // Salted S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input[mypos++].charCodeAt(); - - // Octets 2-9: 8-octet salt value - this.saltValue = input.substring(mypos, mypos+8); - mypos += 8; - this.s2kLength = 9; - break; - - case 3: // Iterated and Salted S2K - // Octet 1: hash algorithm - this.hashAlgorithm = input[mypos++].charCodeAt(); - - // Octets 2-9: 8-octet salt value - this.saltValue = input.substring(mypos, mypos+8); - mypos += 8; - - // Octet 10: count, a one-octet, coded value - this.EXPBIAS = 6; - var c = input[mypos++].charCodeAt(); - this.count = (16 + (c & 15)) << ((c >> 4) + this.EXPBIAS); - this.s2kLength = 10; - break; - - case 2: // Reserved value - default: - util.print_error("unknown s2k type! "+this.type); - break; - } - return this; - } - - - /** - * writes an s2k hash based on the inputs. - * @return [String] produced key of hashAlgorithm hash length - */ - function write(type, hash, passphrase, salt, c){ - this.type = type; - if(this.type == 3){this.saltValue = salt; - this.hashAlgorithm = hash; - this.count = (16 + (c & 15)) << ((c >> 4) + 6); - this.s2kLength = 10; - } - return this.produce_key(passphrase); - } - - /** - * produces a key using the specified passphrase and the defined hashAlgorithm - * @param passphrase [String] passphrase containing user input - * @return [String] produced key with a length corresponding to hashAlgorithm hash length - */ - function produce_key(passphrase, numBytes) { - if (this.type == 0) { - return openpgp_crypto_hashData(this.hashAlgorithm,passphrase); - } else if (this.type == 1) { - return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+passphrase); - } else if (this.type == 3) { - var isp = []; - isp[0] = this.saltValue+passphrase; - while (isp.length*(this.saltValue+passphrase).length < this.count) - isp.push(this.saltValue+passphrase); - isp = isp.join(''); - if (isp.length > this.count) - isp = isp.substr(0, this.count); - if(numBytes && (numBytes == 24 || numBytes == 32)){ //This if accounts for RFC 4880 3.7.1.1 -- If hash size is greater than block size, use leftmost bits. If blocksize larger than hash size, we need to rehash isp and prepend with 0. - var key = openpgp_crypto_hashData(this.hashAlgorithm,isp); - return key + openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+isp); - } - return openpgp_crypto_hashData(this.hashAlgorithm,isp); - } else return null; - } - - this.read = read; - this.write = write; - this.produce_key = produce_key; -} -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// Hint: We hold our MPIs as an array of octets in big endian format preceeding a two -// octet scalar: MPI: [a,b,c,d,e,f] -// - MPI size: (a << 8) | b -// - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) - -/** - * Implementation of type MPI (RFC4880 3.2) - * Multiprecision integers (also called MPIs) are unsigned integers used - * to hold large integers such as the ones used in cryptographic - * calculations. - * An MPI consists of two pieces: a two-octet scalar that is the length - * of the MPI in bits followed by a string of octets that contain the - * actual integer. - */ -function openpgp_type_mpi() { - this.MPI = null; - this.mpiBitLength = null; - this.mpiByteLength = null; - this.data = null; - /** - * parsing function for a mpi (RFC 4880 3.2). - * @param input [string] payload of mpi data - * @param position [integer] position to start reading from the input string - * @param len [integer] length of the packet or the remaining length of input at position - * @return [openpgp_type_mpi] object representation - */ - function read(input, position, len) { - var mypos = position; - - this.mpiBitLength = (input[mypos++].charCodeAt() << 8) | input[mypos++].charCodeAt(); - - // Additional rules: - // - // The size of an MPI is ((MPI.length + 7) / 8) + 2 octets. - // - // The length field of an MPI describes the length starting from its - // most significant non-zero bit. Thus, the MPI [00 02 01] is not - // formed correctly. It should be [00 01 01]. - - // TODO: Verification of this size method! This size calculation as - // specified above is not applicable in JavaScript - this.mpiByteLength = (this.mpiBitLength - (this.mpiBitLength % 8)) / 8; - if (this.mpiBitLength % 8 != 0) - this.mpiByteLength++; - - this.MPI = input.substring(mypos,mypos+this.mpiByteLength); - this.data = input.substring(position, position+2+this.mpiByteLength); - this.packetLength = this.mpiByteLength +2; - return this; - } - - /** - * generates debug output (pretty print) - * @return String which gives some information about the mpi - */ - function toString() { - var r = " MPI("+this.mpiBitLength+"b/"+this.mpiByteLength+"B) : 0x"; - r+=util.hexstrdump(this.MPI); - return r+'\n'; - } - - /** - * converts the mpi to an BigInteger object - * @return [BigInteger] - */ - function getBigInteger() { - return new BigInteger(util.hexstrdump(this.MPI),16); - } - - - function getBits(num) { - for (var i = 0; i < 9; i++) - if (num >> i == 0) - return i; - } - - /** - * gets the length of the mpi in bytes - * @return [integer] mpi byte length - */ - function getByteLength() { - return this.mpiByteLength; - } - - /** - * creates an mpi from the specified string - * @param data [String] data to read the mpi from - * @return [openpgp_type_mpi] - */ - function create(data) { - this.MPI = data; - this.mpiBitLength = (data.length -1) *8 + getBits(data.charCodeAt(0)); - this.mpiByteLength = data.length; - return this; - } - - /** - * converts the mpi object to a string as specified in RFC4880 3.2 - * @return [String] mpi byte representation - */ - function toBin() { - var result = String.fromCharCode((this.mpiBitLength >> 8) & 0xFF); - result += String.fromCharCode(this.mpiBitLength & 0xFF); - result += this.MPI; - return result; - } - - this.read = read; - this.toBigInteger = getBigInteger; - this.toString = toString; - this.create = create; - this.toBin = toBin; - this.getByteLength = getByteLength; -} - -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * Implementation of type key id (RFC4880 3.3) - * A Key ID is an eight-octet scalar that identifies a key. - Implementations SHOULD NOT assume that Key IDs are unique. The - section "Enhanced Key Formats" below describes how Key IDs are - formed. - */ -function openpgp_type_keyid() { - /** - * parsing method for a key id - * @param input [String] input to read the key id from - * @param position [integer] position where to start reading the key id from input - * @return this object - */ - function read_packet(input, position) { - this.bytes = input.substring(position, position+8); - return this; - } - - /** - * generates debug output (pretty print) - * @return [String] Key Id as hexadecimal string - */ - function toString() { - return util.hexstrdump(this.bytes); - } - - this.read_packet = read_packet; - this.toString = toString; -}; -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -function openpgp_msg_message() { - - // -1 = no valid passphrase submitted - // -2 = no private key found - // -3 = decryption error - // text = valid decryption - this.text = ""; - - /** - * Decrypts a message and generates user interface message out of the found. - * MDC will be verified as well as message signatures - * @param private_key [openpgp_msg_privatekey] the private the message is encrypted with (corresponding to the session key) - * @param sessionkey [openpgp_packet_encryptedsessionkey] the session key to be used to decrypt the message - * @return [String] plaintext of the message or null on error - */ - function decrypt(private_key, sessionkey) { - return this.decryptAndVerifySignature(private_key, sessionkey).text; - } - - /** - * Decrypts a message and generates user interface message out of the found. - * MDC will be verified as well as message signatures - * @param private_key [openpgp_msg_privatekey] the private the message is encrypted with (corresponding to the session key) - * @param sessionkey [openpgp_packet_encryptedsessionkey] the session key to be used to decrypt the message - * @param pubkey [openpgp_msg_publickey] Array of public keys to check signature against. If not provided, checks local keystore. - * @return [String] plaintext of the message or null on error - */ - function decryptAndVerifySignature(private_key, sessionkey, pubkey) { - if (private_key == null || sessionkey == null || sessionkey == "") - return null; - var decrypted = sessionkey.decrypt(this, private_key.keymaterial); - if (decrypted == null) - return null; - var packet; - var position = 0; - var len = decrypted.length; - var validSignatures = new Array(); - util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",decrypted); - - while (position != decrypted.length && (packet = openpgp_packet.read_packet(decrypted, position, len)) != null) { - if (packet.tagType == 8) { - this.text = packet.decompress(); - decrypted = packet.decompress(); - } - util.print_debug(packet.toString()); - position += packet.headerLength+packet.packetLength; - if (position > 38) - util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",decrypted.substring(position)); - len = decrypted.length - position; - if (packet.tagType == 11) { - this.text = packet.data; - util.print_info("message successfully decrypted"); - } - if (packet.tagType == 19) - // ignore.. we checked that already in a more strict way. - continue; - if (packet.tagType == 2 && packet.signatureType < 3) { - if(!pubkey || pubkey.length == 0 ){ - var pubkey = openpgp.keyring.getPublicKeysForKeyId(packet.issuerKeyId); - } - if (pubkey.length == 0) { - util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(packet.issuerKeyId)+". Public key not found in keyring."); - validSignatures[validSignatures.length] = false; - } else { - if(packet.verify(this.text.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"),pubkey[0]) && pubkey[0].obj.validate()){ - util.print_info("Found Good Signature from "+pubkey[0].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); - validSignatures[validSignatures.length] = true; - } - else{ - util.print_error("Signature verification failed: Bad Signature from "+pubkey[0].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); - validSignatures[validSignatures.length] = false; - } - } - } - } - if (this.text == "") { - this.text = decrypted; - } - return {text:this.text, validSignatures:validSignatures}; - } - - /** - * Verifies a message signature. This function can be called after read_message if the message was signed only. - * @param pubkey [openpgp_msg_publickey] Array of public keys to check signature against. If not provided, checks local keystore. - * @return [boolean] true if the signature was correct; otherwise false - */ - function verifySignature(pubkey) { - var result = false; - if (this.type == 2) { - if(!pubkey || pubkey.length == 0){ - var pubkey; - if (this.signature.version == 4) { - pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.issuerKeyId); - } else if (this.signature.version == 3) { - pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.keyId); - } else { - util.print_error("unknown signature type on message!"); - return false; - } - } - if (pubkey.length == 0) - util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(this.signature.issuerKeyId)+". Public key not found in keyring."); - else { - for (var i = 0 ; i < pubkey.length; i++) { - var tohash = this.text.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"); - if (this.signature.verify(tohash.substring(0, tohash.length -2), pubkey[i])) { - util.print_info("Found Good Signature from "+pubkey[i].obj.userIds[i].text+" (0x"+util.hexstrdump(pubkey[i].obj.getKeyId()).substring(8)+")"); - result = true; - } else { - util.print_error("Signature verification failed: Bad Signature from "+pubkey[i].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); - } - } - } - } - return result; - } - - function toString() { - var result = "Session Keys:\n"; - if (this.sessionKeys !=null) - for (var i = 0; i < this.sessionKeys.length; i++) { - result += this.sessionKeys[i].toString(); - } - result += "\n\n EncryptedData:\n"; - if(this.encryptedData != null) - result += this.encryptedData.toString(); - - result += "\n\n Signature:\n"; - if(this.signature != null) - result += this.signature.toString(); - - result += "\n\n Text:\n" - if(this.signature != null) - result += this.text; - return result; - } - this.decrypt = decrypt; - this.decryptAndVerifySignature = decryptAndVerifySignature; - this.verifySignature = verifySignature; - this.toString = toString; -} -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var Util = function() { - - this.emailRegEx = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; - - this.hexdump = function(str) { - var r=[]; - var e=str.length; - var c=0; - var h; - var i = 0; - while(c' - * @param str [String] string of the debug message - * @return [String] an HTML tt entity containing a paragraph with a style attribute where the debug message is HTMLencoded in. - */ - this.print_debug = function(str) { - if (openpgp.config.debug) { - str = openpgp_encoding_html_encode(str); - showMessages("

"+str.replace(/\n/g,"
")+"

"); - } - }; - - /** - * Helper function to print a debug message. Debug - * messages are only printed if - * openpgp.config.debug is set to true. The calling - * Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
' - * Different than print_debug because will call hexstrdump iff necessary. - * @param str [String] string of the debug message - * @return [String] an HTML tt entity containing a paragraph with a style attribute where the debug message is HTMLencoded in. - */ - this.print_debug_hexstr_dump = function(str,strToHex) { - if (openpgp.config.debug) { - str = str + this.hexstrdump(strToHex); - str = openpgp_encoding_html_encode(str); - showMessages("

"+str.replace(/\n/g,"
")+"

"); - } - }; - - /** - * Helper function to print an error message. - * The calling Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
' - * @param str [String] string of the error message - * @return [String] a HTML paragraph entity with a style attribute containing the HTML encoded error message - */ - this.print_error = function(str) { - str = openpgp_encoding_html_encode(str); - showMessages("

ERROR: "+str.replace(/\n/g,"
")+"

"); - }; - - /** - * Helper function to print an info message. - * The calling Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
'. - * @param str [String] string of the info message - * @return [String] a HTML paragraph entity with a style attribute containing the HTML encoded info message - */ - this.print_info = function(str) { - str = openpgp_encoding_html_encode(str); - showMessages("

INFO: "+str.replace(/\n/g,"
")+"

"); - }; - - this.print_warning = function(str) { - str = openpgp_encoding_html_encode(str); - showMessages("

WARNING: "+str.replace(/\n/g,"
")+"

"); - }; - - this.getLeftNBits = function (string, bitcount) { - var rest = bitcount % 8; - if (rest == 0) - return string.substring(0, bitcount / 8); - var bytes = (bitcount - rest) / 8 +1; - var result = string.substring(0, bytes); - return this.shiftRight(result, 8-rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; - /** - * Shifting a string to n bits right - * @param value [String] the string to shift - * @param bitcount [Integer] amount of bits to shift (MUST be smaller than 9) - * @return [String] resulting string. - */ - this.shiftRight = function(value, bitcount) { - var temp = util.str2bin(value); - if (bitcount % 8 != 0) { - for (var i = temp.length-1; i >= 0; i--) { - temp[i] >>= bitcount % 8; - if (i > 0) - temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; - } - } else { - return value; - } - return util.bin2str(temp); - }; - - /** - * Return the algorithm type as string - * @return [String] String representing the message type - */ - this.get_hashAlgorithmString = function(algo) { - switch(algo) { - case 1: - return "MD5"; - case 2: - return "SHA1"; - case 3: - return "RIPEMD160"; - case 8: - return "SHA256"; - case 9: - return "SHA384"; - case 10: - return "SHA512"; - case 11: - return "SHA224"; - } - return "unknown"; - }; -}; - -/** - * an instance that should be used. - */ -var util = new Util(); -JXG = {exists: (function(undefined){return function(v){return !(v===undefined || v===null);}})()}; -JXG.decompress = function(str) {return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip()[0][0]);}; -/* - Copyright 2008-2012 - Matthias Ehmann, - Michael Gerhaeuser, - Carsten Miller, - Bianca Valentin, - Alfred Wassermann, - Peter Wilfahrt - - This file is part of JSXGraph. - - Dual licensed under the Apache License Version 2.0, or LGPL Version 3 licenses. - - You should have received a copy of the GNU Lesser General Public License - along with JSXCompressor. If not, see . - - You should have received a copy of the Apache License along with JSXCompressor. - If not, see . - -*/ - -/** - * @fileoverview Utilities for uncompressing and base64 decoding + * Of course, this soft is provided "as is" without express or implied + * warranty of any kind. */ -/** - * @class Util class - * Class for gunzipping, unzipping and base64 decoding of files. - * It is used for reading GEONExT, Geogebra and Intergeo files. - * - * Only Huffman codes are decoded in gunzip. - * The code is based on the source code for gunzip.c by Pasi Ojala - * @see http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c - * @see http://www.cs.tut.fi/~albert - */ -JXG.Util = {}; - -/** - * Unzip zip files +function MD5(entree) { + var hex = md5(entree); + var bin = util.hex2bin(hex); + return bin; +} + +function md5cycle(x, k) { +var a = x[0], b = x[1], c = x[2], d = x[3]; + +a = ff(a, b, c, d, k[0], 7, -680876936); +d = ff(d, a, b, c, k[1], 12, -389564586); +c = ff(c, d, a, b, k[2], 17, 606105819); +b = ff(b, c, d, a, k[3], 22, -1044525330); +a = ff(a, b, c, d, k[4], 7, -176418897); +d = ff(d, a, b, c, k[5], 12, 1200080426); +c = ff(c, d, a, b, k[6], 17, -1473231341); +b = ff(b, c, d, a, k[7], 22, -45705983); +a = ff(a, b, c, d, k[8], 7, 1770035416); +d = ff(d, a, b, c, k[9], 12, -1958414417); +c = ff(c, d, a, b, k[10], 17, -42063); +b = ff(b, c, d, a, k[11], 22, -1990404162); +a = ff(a, b, c, d, k[12], 7, 1804603682); +d = ff(d, a, b, c, k[13], 12, -40341101); +c = ff(c, d, a, b, k[14], 17, -1502002290); +b = ff(b, c, d, a, k[15], 22, 1236535329); + +a = gg(a, b, c, d, k[1], 5, -165796510); +d = gg(d, a, b, c, k[6], 9, -1069501632); +c = gg(c, d, a, b, k[11], 14, 643717713); +b = gg(b, c, d, a, k[0], 20, -373897302); +a = gg(a, b, c, d, k[5], 5, -701558691); +d = gg(d, a, b, c, k[10], 9, 38016083); +c = gg(c, d, a, b, k[15], 14, -660478335); +b = gg(b, c, d, a, k[4], 20, -405537848); +a = gg(a, b, c, d, k[9], 5, 568446438); +d = gg(d, a, b, c, k[14], 9, -1019803690); +c = gg(c, d, a, b, k[3], 14, -187363961); +b = gg(b, c, d, a, k[8], 20, 1163531501); +a = gg(a, b, c, d, k[13], 5, -1444681467); +d = gg(d, a, b, c, k[2], 9, -51403784); +c = gg(c, d, a, b, k[7], 14, 1735328473); +b = gg(b, c, d, a, k[12], 20, -1926607734); + +a = hh(a, b, c, d, k[5], 4, -378558); +d = hh(d, a, b, c, k[8], 11, -2022574463); +c = hh(c, d, a, b, k[11], 16, 1839030562); +b = hh(b, c, d, a, k[14], 23, -35309556); +a = hh(a, b, c, d, k[1], 4, -1530992060); +d = hh(d, a, b, c, k[4], 11, 1272893353); +c = hh(c, d, a, b, k[7], 16, -155497632); +b = hh(b, c, d, a, k[10], 23, -1094730640); +a = hh(a, b, c, d, k[13], 4, 681279174); +d = hh(d, a, b, c, k[0], 11, -358537222); +c = hh(c, d, a, b, k[3], 16, -722521979); +b = hh(b, c, d, a, k[6], 23, 76029189); +a = hh(a, b, c, d, k[9], 4, -640364487); +d = hh(d, a, b, c, k[12], 11, -421815835); +c = hh(c, d, a, b, k[15], 16, 530742520); +b = hh(b, c, d, a, k[2], 23, -995338651); + +a = ii(a, b, c, d, k[0], 6, -198630844); +d = ii(d, a, b, c, k[7], 10, 1126891415); +c = ii(c, d, a, b, k[14], 15, -1416354905); +b = ii(b, c, d, a, k[5], 21, -57434055); +a = ii(a, b, c, d, k[12], 6, 1700485571); +d = ii(d, a, b, c, k[3], 10, -1894986606); +c = ii(c, d, a, b, k[10], 15, -1051523); +b = ii(b, c, d, a, k[1], 21, -2054922799); +a = ii(a, b, c, d, k[8], 6, 1873313359); +d = ii(d, a, b, c, k[15], 10, -30611744); +c = ii(c, d, a, b, k[6], 15, -1560198380); +b = ii(b, c, d, a, k[13], 21, 1309151649); +a = ii(a, b, c, d, k[4], 6, -145523070); +d = ii(d, a, b, c, k[11], 10, -1120210379); +c = ii(c, d, a, b, k[2], 15, 718787259); +b = ii(b, c, d, a, k[9], 21, -343485551); + +x[0] = add32(a, x[0]); +x[1] = add32(b, x[1]); +x[2] = add32(c, x[2]); +x[3] = add32(d, x[3]); + +} + +function cmn(q, a, b, x, s, t) { +a = add32(add32(a, q), add32(x, t)); +return add32((a << s) | (a >>> (32 - s)), b); +} + +function ff(a, b, c, d, x, s, t) { +return cmn((b & c) | ((~b) & d), a, b, x, s, t); +} + +function gg(a, b, c, d, x, s, t) { +return cmn((b & d) | (c & (~d)), a, b, x, s, t); +} + +function hh(a, b, c, d, x, s, t) { +return cmn(b ^ c ^ d, a, b, x, s, t); +} + +function ii(a, b, c, d, x, s, t) { +return cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +function md51(s) { +txt = ''; +var n = s.length, +state = [1732584193, -271733879, -1732584194, 271733878], i; +for (i=64; i<=s.length; i+=64) { +md5cycle(state, md5blk(s.substring(i-64, i))); +} +s = s.substring(i-64); +var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; +for (i=0; i>2] |= s.charCodeAt(i) << ((i%4) << 3); +tail[i>>2] |= 0x80 << ((i%4) << 3); +if (i > 55) { +md5cycle(state, tail); +for (i=0; i<16; i++) tail[i] = 0; +} +tail[14] = n*8; +md5cycle(state, tail); +return state; +} + +/* there needs to be support for Unicode here, + * unless we pretend that we can redefine the MD-5 + * algorithm for multi-byte characters (perhaps + * by adding every four 16-bit characters and + * shortening the sum to 32 bits). Otherwise + * I suggest performing MD-5 as if every character + * was two bytes--e.g., 0040 0025 = @%--but then + * how will an ordinary MD-5 sum be matched? + * There is no way to standardize text to something + * like UTF-8 before transformation; speed cost is + * utterly prohibitive. The JavaScript standard + * itself needs to look at this: it should start + * providing access to strings as preformed UTF-8 + * 8-bit unsigned value arrays. */ -JXG.Util.Unzip = function (barray){ - var outputArr = [], - output = "", - debug = false, - gpflags, - files = 0, - unzipped = [], - crc, - buf32k = new Array(32768), - bIdx = 0, - modeZIP=false, - - CRC, SIZE, - - bitReverse = [ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff - ], - - cplens = [ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ], - - cplext = [ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 - ], /* 99==invalid */ - - cpdist = [ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, - 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, - 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, - 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 - ], - - cpdext = [ - 0, 0, 0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13 - ], - - border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], - - bA = barray, - - bytepos=0, - bitpos=0, - bb = 1, - bits=0, - - NAMEMAX = 256, - - nameBuf = [], - - fileout; - - function readByte(){ - bits+=8; - if (bytepos"); - return bA[bytepos++]; - } else - return -1; - }; - - function byteAlign(){ - bb = 1; - }; - - function readBit(){ - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb==0){ - bb = readByte(); - carry = (bb & 1); - bb = (bb>>1) | 0x80; - } - return carry; - }; - - function readBits(a) { - var res = 0, - i = a; - - while(i--) { - res = (res<<1) | readBit(); - } - if(a) { - res = bitReverse[res]>>(8-a); - } - return res; - }; - - function flushBuffer(){ - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - }; - function addBuffer(a){ - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if(bIdx==0x8000){ - //document.write('ADDBUFFER:'+buf32k); - bIdx=0; - } - }; - - function HufNode() { - this.b0=0; - this.b1=0; - this.jump = null; - this.jumppos = -1; - }; - - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos=0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0]=0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - }; - - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("
len:"+len+" treepos:"+treepos); - if(len==17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("
IsPat "+tmp); - if(tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("
b0 "+curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("
b0 "+curplace.b0); - if(Rec()) - return -1; - } - tmp = IsPat(); - if(tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if(Rec()) - return -1; - } - len--; - return 0; - }; - - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("
createtree
"); - if (debug) - document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show); - Places = currentTree; - treepos=0; - flens = lengths; - fmax = numval; - for (i=0;i<17;i++) - fpos[i] = 0; - len = 0; - if(Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug){ - document.write('
Tree: '+Places.length); - for (var a=0;a<32;a++){ - document.write("Places["+a+"].b0="+Places[a].b0+"
"); - document.write("Places["+a+"].b1="+Places[a].b1+"
"); - } - } - - /*if(show) { - var tmp; - for(tmp=currentTree;tmpjump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); - if(!(tmp.b0 & 0x8000)) { - //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); - } - if(!(tmp.b1 & 0x8000)) { - if((tmp.b0 & 0x8000)) - fprintf(stdout, " "); - fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); - } - fprintf(stdout, "\n"); - } - }*/ - return 0; - }; - - function DecodeValue(currentTree) { - var len, i, - xtreepos=0, - X = currentTree[xtreepos], - b; - - /* decode one symbol of the data */ - while(1) { - b=readBit(); - if (debug) - document.write("b="+b); - if(b) { - if(!(X.b1 & 0x8000)){ - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i=0;i>1); - if(j > 23) { - j = (j<<1) | readBit(); /* 48..255 */ - - if(j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j<<1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if(j > 143) { - j = j+136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ - } - if(j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if(j == 256) { - /* EOF */ - break; - } else { - var len, dist; - - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; - - j = bitReverse[readBits(5)]>>3; - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for(j=0;jparam: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); - for(j=0; j<19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("
"); - for(j=0; jll:'+ll); - len = distanceTree.length; - for (i=0; idistanceTree"); - for(var a=0;a"+distanceTree[a].b0+" "+distanceTree[a].b1+" "+distanceTree[a].jump+" "+distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) - document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); - */ - } - } - //document.write('
tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z=-1; - if (debug) - document.write("
n="+n+" bits: "+bits+"
"); - while(i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("
"+z+" i:"+i+" decode: "+j+" bits "+bits+"
"); - if(j<16) { // length of code in bits (0..15) - ll[i++] = j; - } else if(j==16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if(i+j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i-1] : 0; - while(j--) { - ll[i++] = l; - } - } else { - if(j==17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if(i+j > n) { - flushBuffer(); - return 1; - } - while(j--) { - ll[i++] = 0; - } - } - } - /*for(j=0; jliteralTree"); - while(1) { - j = DecodeValue(literalTree); - if(j >= 256) { // In C64: if carry set - var len, dist; - j -= 256; - if(j == 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while(len--) { - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } - } - } while(!last); - flushBuffer(); - - byteAlign(); - return 0; -}; - -JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i=0;i"); - } - */ - //alert(bA); - nextFile(); - return unzipped; - }; - - function nextFile(){ - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: "+tmp[0]+" "+tmp[1]); - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("da",16)){ //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("9c",16)){ //ZLIB - if (debug) - alert("ZLIB"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "ZLIB"; - files++; - } - if (tmp[0] == parseInt("1f",16) && tmp[1] == parseInt("8b",16)){ //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50",16) && tmp[1] == parseInt("4b",16)){ //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3",16) && tmp[3] == parseInt("4",16)){ - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10); - - gpflags = readByte(); - gpflags |= (readByte()<<8); - if (debug) - alert("gpflags: "+gpflags); - - var method = readByte(); - method |= (readByte()<<8); - if (debug) - alert("method: "+method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - - var compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - var size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize); - - var filelen = readByte(); - filelen |= (readByte()<<8); - - var extralen = readByte(); - extralen |= (readByte()<<8); - - if (debug) - alert("filelen "+filelen); - i = 0; - nameBuf = []; - while (filelen--){ - var c = readByte(); - if (c == "/" | c ==":"){ - i = 0; - } else if (i < NAMEMAX-1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: "+nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen){ - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size = 0 && fileOut.charAt(fileout.length-1)=="/"){ - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8){ - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - }; - -function skipdir(){ - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50",16) && - tmp[1] == parseInt("4b",16) && - tmp[2] == parseInt("07",16) && - tmp[3] == parseInt("08",16)) - { - crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - } else { - crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24); - } - - compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("CRC:"); - } - - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug){ - if ((gpflags & ~(parseInt("1f",16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)){ - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256*tmp[1]; - if (debug) - alert("Extra field size: "+len); - for (i=0;ihttp://www.webtoolkit.info/ -*/ -JXG.Util.Base64 = { - - // private property - _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", - - // public method for encoding - encode : function (input) { - var output = [], - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0; - - input = JXG.Util.Base64._utf8_encode(input); - - while (i < input.length) { - - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4)].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode : function (input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var string = [], - i = 0, - c = 0, c2 = 0, c3 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function (stripped, wrap){ - var lines = [], lineno, i, - destripped = []; - - if (wrap==null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i]=stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length]=stripped.substr(lineno * wrap, stripped.length-(lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function (input){ - var dec = this.decode(input), - ar = [], i; - for (i=0;i255){ - switch (c) { - case 8364: c=128; - break; - case 8218: c=130; - break; - case 402: c=131; - break; - case 8222: c=132; - break; - case 8230: c=133; - break; - case 8224: c=134; - break; - case 8225: c=135; - break; - case 710: c=136; - break; - case 8240: c=137; - break; - case 352: c=138; - break; - case 8249: c=139; - break; - case 338: c=140; - break; - case 381: c=142; - break; - case 8216: c=145; - break; - case 8217: c=146; - break; - case 8220: c=147; - break; - case 8221: c=148; - break; - case 8226: c=149; - break; - case 8211: c=150; - break; - case 8212: c=151; - break; - case 732: c=152; - break; - case 8482: c=153; - break; - case 353: c=154; - break; - case 8250: c=155; - break; - case 339: c=156; - break; - case 382: c=158; - break; - case 376: c=159; - break; - default: - break; - } - } - return c; -}; - -/** - * Decoding string into utf-8 - * @param {String} string to decode - * @return {String} utf8 decoded string - */ -JXG.Util.utf8Decode = function(utftext) { - var string = []; - var i = 0; - var c = 0, c1 = 0, c2 = 0, c3; - if (!JXG.exists(utftext)) return ''; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - }; - return string.join(''); -}; - -/** - * Generate a random uuid. - * http://www.broofa.com - * mailto:robert@broofa.com - * - * Copyright (c) 2010 Robert Kieffer - * Dual licensed under the MIT and GPL licenses. - * - * EXAMPLES: - * >>> Math.uuid() - * "92329D39-6F5C-4520-ABFC-AAB64544E172" - */ -JXG.Util.genUUID = function() { - // Private array of chars to use - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), - uuid = new Array(36), rnd=0, r; - - for (var i = 0; i < 36; i++) { - if (i==8 || i==13 || i==18 || i==23) { - uuid[i] = '-'; - } else if (i==14) { - uuid[i] = '4'; - } else { - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } - } - - return uuid.join(''); -}; - -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers symmetric crypto interface - -/** - * Symmetrically encrypts data using prefixedrandom, a key with length - * depending on the algorithm in openpgp_cfb mode with or without resync - * (MDC style) - * @param prefixrandom secure random bytes as string in length equal to the - * block size of the algorithm used (use openpgp_crypto_getPrefixRandom(algo) - * to retrieve that string - * @param algo [Integer] algorithm to use (see RFC4880 9.2) - * @param key [String] key as string. length is depending on the algorithm used - * @param data [String] data to encrypt - * @param openpgp_cfb [boolean] - * @return [String] encrypted data - */ -function openpgp_crypto_symmetricEncrypt(prefixrandom, algo, key, data, openpgp_cfb) { - switch(algo) { - case 0: // Plaintext or unencrypted data - return data; // blockcipherencryptfn, plaintext, block_size, key - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - return openpgp_cfb_encrypt(prefixrandom, desede, data,8,key, openpgp_cfb).substring(0, data.length + 10); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - return openpgp_cfb_encrypt(prefixrandom, cast5_encrypt, data,8,key, openpgp_cfb).substring(0, data.length + 10); - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - return openpgp_cfb_encrypt(prefixrandom, BFencrypt, data,8,key, openpgp_cfb).substring(0, data.length + 10); - case 7: // AES with 128-bit key [AES] - case 8: // AES with 192-bit key - case 9: // AES with 256-bit key - return openpgp_cfb_encrypt(prefixrandom, AESencrypt, data, 16, keyExpansion(key), openpgp_cfb).substring(0, data.length + 18); - case 10: // Twofish with 256-bit key [TWOFISH] - return openpgp_cfb_encrypt(prefixrandom, TFencrypt, data,16, key, openpgp_cfb).substring(0, data.length + 18); - case 1: // IDEA [IDEA] - util.print_error("IDEA Algorithm not implemented"); - return null; - default: - return null; - } +function md5blk(s) { /* I figured global was faster. */ +var md5blks = [], i; /* Andy King said do it this way. */ +for (i=0; i<64; i+=4) { +md5blks[i>>2] = s.charCodeAt(i) ++ (s.charCodeAt(i+1) << 8) ++ (s.charCodeAt(i+2) << 16) ++ (s.charCodeAt(i+3) << 24); } - -/** - * Symmetrically decrypts data using a key with length depending on the - * algorithm in openpgp_cfb mode with or without resync (MDC style) - * @param algo [Integer] algorithm to use (see RFC4880 9.2) - * @param key [String] key as string. length is depending on the algorithm used - * @param data [String] data to be decrypted - * @param openpgp_cfb [boolean] if true use the resync (for encrypteddata); - * otherwise use without the resync (for MDC encrypted data) - * @return [String] plaintext data - */ -function openpgp_crypto_symmetricDecrypt(algo, key, data, openpgp_cfb) { - util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nalgo:"+algo+"\nencrypteddata:",data); - var n = 0; - if (!openpgp_cfb) - n = 2; - switch(algo) { - case 0: // Plaintext or unencrypted data - return data; - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - return openpgp_cfb_decrypt(desede, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - return openpgp_cfb_decrypt(cast5_encrypt, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - return openpgp_cfb_decrypt(BFencrypt, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); - case 7: // AES with 128-bit key [AES] - case 8: // AES with 192-bit key - case 9: // AES with 256-bit key - return openpgp_cfb_decrypt(AESencrypt, 16, keyExpansion(key), data, openpgp_cfb).substring(n, (data.length+n)-18); - case 10: // Twofish with 256-bit key [TWOFISH] - var result = openpgp_cfb_decrypt(TFencrypt, 16, key, data, openpgp_cfb).substring(n, (data.length+n)-18); - return result; - case 1: // IDEA [IDEA] - util.print_error(""+ (algo == 1 ? "IDEA Algorithm not implemented" : "Twofish Algorithm not implemented")); - return null; - default: - } - return null; -}// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers crypto interface - -/** - * Encrypts data using the specified public key multiprecision integers - * and the specified algorithm. - * @param algo [Integer] Algorithm to be used (See RFC4880 9.1) - * @param publicMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers - * @param data [openpgp_type_mpi] data to be encrypted as MPI - * @return [Object] if RSA an openpgp_type_mpi; if elgamal encryption an array of two - * openpgp_type_mpi is returned; otherwise null - */ -function openpgp_crypto_asymetricEncrypt(algo, publicMPIs, data) { - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var n = publicMPIs[0].toBigInteger(); - var e = publicMPIs[1].toBigInteger(); - var m = data.toBigInteger(); - return rsa.encrypt(m,e,n).toMPI(); - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - var elgamal = new Elgamal(); - var p = publicMPIs[0].toBigInteger(); - var g = publicMPIs[1].toBigInteger(); - var y = publicMPIs[2].toBigInteger(); - var m = data.toBigInteger(); - return elgamal.encrypt(m,g,p,y); - default: - return null; - } -} - -/** - * Decrypts data using the specified public key multiprecision integers of the private key, - * the specified secretMPIs of the private key and the specified algorithm. - * @param algo [Integer] Algorithm to be used (See RFC4880 9.1) - * @param publicMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers of the public key part of the private key - * @param secretMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers of the private key used - * @param data [openpgp_type_mpi] data to be encrypted as MPI - * @return [BigInteger] returns a big integer containing the decrypted data; otherwise null - */ - -function openpgp_crypto_asymetricDecrypt(algo, publicMPIs, secretMPIs, dataMPIs) { - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var d = secretMPIs[0].toBigInteger(); - var p = secretMPIs[1].toBigInteger(); - var q = secretMPIs[2].toBigInteger(); - var u = secretMPIs[3].toBigInteger(); - var m = dataMPIs[0].toBigInteger(); - return rsa.decrypt(m, d, p, q, u); - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - var elgamal = new Elgamal(); - var x = secretMPIs[0].toBigInteger(); - var c1 = dataMPIs[0].toBigInteger(); - var c2 = dataMPIs[1].toBigInteger(); - var p = publicMPIs[0].toBigInteger(); - return elgamal.decrypt(c1,c2,p,x); - default: - return null; - } - -} - -/** - * generate random byte prefix as string for the specified algorithm - * @param algo [Integer] algorithm to use (see RFC4880 9.2) - * @return [String] random bytes with length equal to the block - * size of the cipher - */ -function openpgp_crypto_getPrefixRandom(algo) { - switch(algo) { - case 2: - case 3: - case 4: - return openpgp_crypto_getRandomBytes(8); - case 7: - case 8: - case 9: - case 10: - return openpgp_crypto_getRandomBytes(16); - default: - return null; - } -} - -/** - * retrieve the MDC prefixed bytes by decrypting them - * @param algo [Integer] algorithm to use (see RFC4880 9.2) - * @param key [String] key as string. length is depending on the algorithm used - * @param data [String] encrypted data where the prefix is decrypted from - * @return [String] plain text data of the prefixed data - */ -function openpgp_crypto_MDCSystemBytes(algo, key, data) { - util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nencrypteddata:",data); - switch(algo) { - case 0: // Plaintext or unencrypted data - return data; - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - return openpgp_cfb_mdc(desede, 8, key, data, openpgp_cfb); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - return openpgp_cfb_mdc(cast5_encrypt, 8, key, data); - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - return openpgp_cfb_mdc(BFencrypt, 8, key, data); - case 7: // AES with 128-bit key [AES] - case 8: // AES with 192-bit key - case 9: // AES with 256-bit key - return openpgp_cfb_mdc(AESencrypt, 16, keyExpansion(key), data); - case 10: - return openpgp_cfb_mdc(TFencrypt, 16, key, data); - case 1: // IDEA [IDEA] - util.print_error(""+ (algo == 1 ? "IDEA Algorithm not implemented" : "Twofish Algorithm not implemented")); - return null; - default: - } - return null; -} -/** - * Generating a session key for the specified symmetric algorithm - * @param algo [Integer] algorithm to use (see RFC4880 9.2) - * @return [String] random bytes as a string to be used as a key - */ -function openpgp_crypto_generateSessionKey(algo) { - switch (algo) { - case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) - case 8: // AES with 192-bit key - return openpgp_crypto_getRandomBytes(24); - case 3: // CAST5 (128 bit key, as per [RFC2144]) - case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] - case 7: // AES with 128-bit key [AES] - util.print_debug("length = 16:\n"+util.hexstrdump(openpgp_crypto_getRandomBytes(16))); - return openpgp_crypto_getRandomBytes(16); - case 9: // AES with 256-bit key - case 10:// Twofish with 256-bit key [TWOFISH] - return openpgp_crypto_getRandomBytes(32); - } - return null; -} - -/** - * - * @param algo [Integer] public key algorithm - * @param hash_algo [Integer] hash algorithm - * @param msg_MPIs [Array[openpgp_type_mpi]] signature multiprecision integers - * @param publickey_MPIs [Array[openpgp_type_mpi]] public key multiprecision integers - * @param data [String] data on where the signature was computed on. - * @return true if signature (sig_data was equal to data over hash) - */ -function openpgp_crypto_verifySignature(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { - var calc_hash = openpgp_crypto_hashData(hash_algo, data); - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var n = publickey_MPIs[0].toBigInteger(); - var e = publickey_MPIs[1].toBigInteger(); - var x = msg_MPIs[0].toBigInteger(); - var dopublic = rsa.verify(x,e,n); - var hash = openpgp_encoding_emsa_pkcs1_decode(hash_algo,dopublic.toMPI().substring(2)); - if (hash == -1) { - util.print_error("PKCS1 padding in message or key incorrect. Aborting..."); - return false; - } - return hash == calc_hash; - - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - util.print_error("signing with Elgamal is not defined in the OpenPGP standard."); - return null; - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new DSA(); - var s1 = msg_MPIs[0].toBigInteger(); - var s2 = msg_MPIs[1].toBigInteger(); - var p = publickey_MPIs[0].toBigInteger(); - var q = publickey_MPIs[1].toBigInteger(); - var g = publickey_MPIs[2].toBigInteger(); - var y = publickey_MPIs[3].toBigInteger(); - var m = data; - var dopublic = dsa.verify(hash_algo,s1,s2,m,p,q,g,y); - return dopublic.compareTo(s1) == 0; - default: - return null; - } - +return md5blks; } - -/** - * Create a signature on data using the specified algorithm - * @param hash_algo [Integer] hash algorithm to use (See RFC4880 9.4) - * @param algo [Integer] asymmetric cipher algorithm to use (See RFC4880 9.1) - * @param publicMPIs [Array[openpgp_type_mpi]] public key multiprecision integers of the private key - * @param secretMPIs [Array[openpgp_type_mpi]] private key multiprecision integers which is used to sign the data - * @param data [String] data to be signed - * @return [String or openpgp_type_mpi] - */ -function openpgp_crypto_signData(hash_algo, algo, publicMPIs, secretMPIs, data) { - - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new RSA(); - var d = secretMPIs[0].toBigInteger(); - var n = publicMPIs[0].toBigInteger(); - var m = openpgp_encoding_emsa_pkcs1_encode(hash_algo, data,publicMPIs[0].mpiByteLength); - util.print_debug("signing using RSA"); - return rsa.sign(m, d, n).toMPI(); - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new DSA(); - util.print_debug("DSA Sign: q size in Bytes:"+publicMPIs[1].getByteLength()); - var p = publicMPIs[0].toBigInteger(); - var q = publicMPIs[1].toBigInteger(); - var g = publicMPIs[2].toBigInteger(); - var y = publicMPIs[3].toBigInteger(); - var x = secretMPIs[0].toBigInteger(); - var m = data; - var result = dsa.sign(hash_algo,m, g, p, q, x); - util.print_debug("signing using DSA\n result:"+util.hexstrdump(result[0])+"|"+util.hexstrdump(result[1])); - return result[0]+result[1]; - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - util.print_debug("signing with Elgamal is not defined in the OpenPGP standard."); - return null; - default: - return null; - } -} - -/** - * create a hash on the specified data using the specified algorithm - * @param algo [Integer] hash algorithm type (see RFC4880 9.4) - * @param data [String] data to be hashed - * @return [String] hash value - */ -function openpgp_crypto_hashData(algo, data) { - var hash = null; - switch(algo) { - case 1: // - MD5 [HAC] - hash = MD5(data); - break; - case 2: // - SHA-1 [FIPS180] - hash = str_sha1(data); - break; - case 3: // - RIPE-MD/160 [HAC] - hash = RMDstring(data); - break; - case 8: // - SHA256 [FIPS180] - hash = str_sha256(data); - break; - case 9: // - SHA384 [FIPS180] - hash = str_sha384(data); - break; - case 10:// - SHA512 [FIPS180] - hash = str_sha512(data); - break; - case 11:// - SHA224 [FIPS180] - hash = str_sha224(data); - default: - break; - } - return hash; -} - -/** - * returns the hash size in bytes of the specified hash algorithm type - * @param algo [Integer] hash algorithm type (See RFC4880 9.4) - * @return [Integer] size in bytes of the resulting hash - */ -function openpgp_crypto_getHashByteLength(algo) { - var hash = null; - switch(algo) { - case 1: // - MD5 [HAC] - return 16; - case 2: // - SHA-1 [FIPS180] - case 3: // - RIPE-MD/160 [HAC] - return 20; - case 8: // - SHA256 [FIPS180] - return 32; - case 9: // - SHA384 [FIPS180] - return 48 - case 10:// - SHA512 [FIPS180] - return 64; - case 11:// - SHA224 [FIPS180] - return 28; - } - return null; -} - -/** - * retrieve secure random byte string of the specified length - * @param length [Integer] length in bytes to generate - * @return [String] random byte string - */ -function openpgp_crypto_getRandomBytes(length) { - var result = ''; - for (var i = 0; i < length; i++) { - result += String.fromCharCode(openpgp_crypto_getSecureRandomOctet()); - } - return result; -} - -/** - * return a pseudo-random number in the specified range - * @param from [Integer] min of the random number - * @param to [Integer] max of the random number (max 32bit) - * @return [Integer] a pseudo random number - */ -function openpgp_crypto_getPseudoRandom(from, to) { - return Math.round(Math.random()*(to-from))+from; -} - -/** - * return a secure random number in the specified range - * @param from [Integer] min of the random number - * @param to [Integer] max of the random number (max 32bit) - * @return [Integer] a secure random number - */ -function openpgp_crypto_getSecureRandom(from, to) { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - var bits = ((to-from)).toString(2).length; - while ((buf[0] & (Math.pow(2, bits) -1)) > (to-from)) - window.crypto.getRandomValues(buf); - return from+(Math.abs(buf[0] & (Math.pow(2, bits) -1))); -} - -function openpgp_crypto_getSecureRandomOctet() { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - return buf[0] & 0xFF; -} - -/** - * create a secure random big integer of bits length - * @param bits [Integer] bit length of the MPI to create - * @return [BigInteger] resulting big integer - */ -function openpgp_crypto_getRandomBigInteger(bits) { - if (bits < 0) - return null; - var numBytes = Math.floor((bits+7)/8); - - var randomBits = openpgp_crypto_getRandomBytes(numBytes); - if (bits % 8 > 0) { - - randomBits = String.fromCharCode( - (Math.pow(2,bits % 8)-1) & - randomBits.charCodeAt(0)) + - randomBits.substring(1); - } - return new openpgp_type_mpi().create(randomBits).toBigInteger(); -} - -function openpgp_crypto_getRandomBigIntegerInRange(min, max) { - if (max.compareTo(min) <= 0) - return; - var range = max.subtract(min); - var r = openpgp_crypto_getRandomBigInteger(range.bitLength()); - while (r > range) { - r = openpgp_crypto_getRandomBigInteger(range.bitLength()); - } - return min.add(r); -} - - -//This is a test method to ensure that encryption/decryption with a given 1024bit RSAKey object functions as intended -function openpgp_crypto_testRSA(key){ - debugger; - var rsa = new RSA(); - var mpi = new openpgp_type_mpi(); - mpi.create(openpgp_encoding_eme_pkcs1_encode('ABABABAB', 128)); - var msg = rsa.encrypt(mpi.toBigInteger(),key.ee,key.n); - var result = rsa.decrypt(msg, key.d, key.p, key.q, key.u); -} -/** - * calls the necessary crypto functions to generate a keypair. Called directly by openpgp.js - * @keyType [int] follows OpenPGP algorithm convention. - * @numBits [int] number of bits to make the key to be generated - * @return {privateKey: [openpgp_packet_keymaterial] , publicKey: [openpgp_packet_keymaterial]} - */ -function openpgp_crypto_generateKeyPair(keyType, numBits, passphrase, s2kHash, symmetricEncryptionAlgorithm){ - var privKeyPacket; - var publicKeyPacket; - var d = new Date(); - d = d.getTime()/1000; - var timePacket = String.fromCharCode(Math.floor(d/0x1000000%0x100)) + String.fromCharCode(Math.floor(d/0x10000%0x100)) + String.fromCharCode(Math.floor(d/0x100%0x100)) + String.fromCharCode(Math.floor(d%0x100)); - switch(keyType){ - case 1: - var rsa = new RSA(); - var key = rsa.generate(numBits,"10001"); - privKeyPacket = new openpgp_packet_keymaterial().write_private_key(keyType, key, passphrase, s2kHash, symmetricEncryptionAlgorithm, timePacket); - publicKeyPacket = new openpgp_packet_keymaterial().write_public_key(keyType, key, timePacket); - break; - default: - util.print_error("Unknown keytype "+keyType) - } - return {privateKey: privKeyPacket, publicKey: publicKeyPacket}; -} -/* - * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) - * All Rights Reserved. - * - * Modified by Recurity Labs GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); - -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// RSA implementation - -function SecureRandom(){ - function nextBytes(byteArray){ - for(var n = 0; n < byteArray.length;n++){ - byteArray[n] = openpgp_crypto_getSecureRandomOctet(); - } - } - this.nextBytes = nextBytes; -} - -function RSA() { - /** - * This function uses jsbn Big Num library to decrypt RSA - * @param m - * message - * @param d - * RSA d as BigInteger - * @param p - * RSA p as BigInteger - * @param q - * RSA q as BigInteger - * @param u - * RSA u as BigInteger - * @return {BigInteger} The decrypted value of the message - */ - function decrypt(m, d, p, q, u) { - var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p); - var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q); - util.print_debug("rsa.js decrypt\nxpn:"+util.hexstrdump(xp.toMPI())+"\nxqn:"+util.hexstrdump(xq.toMPI())); - - var t = xq.subtract(xp); - if (t[0] == 0) { - t = xp.subtract(xq); - t = t.multiply(u).mod(q); - t = q.subtract(t); - } else { - t = t.multiply(u).mod(q); - } - return t.multiply(p).add(xp); - } - - /** - * encrypt message - * @param m message as BigInteger - * @param e public MPI part as BigInteger - * @param n public MPI part as BigInteger - * @return BigInteger - */ - function encrypt(m,e,n) { - return m.modPowInt(e, n); - } - - /* Sign and Verify */ - function sign(m,d,n) { - return m.modPow(d, n); - } - - function verify(x,e,n) { - return x.modPowInt(e, n); - } - - // "empty" RSA key constructor - function keyObject() { - this.n = null; - this.e = 0; - this.ee = null; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.u = null; - } - - // Generate a new random private key B bits long, using public expt E - function generate(B,E) { - var key = new keyObject(); - var rng = new SecureRandom(); - var qs = B>>1; - key.e = parseInt(E,16); - key.ee = new BigInteger(E,16); - for(;;) { - for(;;) { - key.p = new BigInteger(B-qs,1,rng); - if(key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) break; - } - for(;;) { - key.q = new BigInteger(qs,1,rng); - if(key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) break; - } - if(key.p.compareTo(key.q) <= 0) { - var t = key.p; - key.p = key.q; - key.q = t; - } - var p1 = key.p.subtract(BigInteger.ONE); - var q1 = key.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if(phi.gcd(key.ee).compareTo(BigInteger.ONE) == 0) { - key.n = key.p.multiply(key.q); - key.d = key.ee.modInverse(phi); - key.dmp1 = key.d.mod(p1); - key.dmq1 = key.d.mod(q1); - key.u = key.p.modInverse(key.q); - break; - } - } - return key; - } - - this.encrypt = encrypt; - this.decrypt = decrypt; - this.verify = verify; - this.sign = sign; - this.generate = generate; - this.keyObject = keyObject; -} -/* - * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) - * All Rights Reserved. - * - * Modified by Recurity Labs GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following condition applies: - * - * All redistributions must retain an intact copy of this copyright notice - * and disclaimer. - */ -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - //if((d&0x80) != 0) d |= -256; - //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [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,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -/* added by Recurity Labs */ - -function nbits(x) { - var n = 1, t; - if ((t = x >>> 16) != 0) { - x = t; - n += 16; - } - if ((t = x >> 8) != 0) { - x = t; - n += 8; - } - if ((t = x >> 4) != 0) { - x = t; - n += 4; - } - if ((t = x >> 2) != 0) { - x = t; - n += 2; - } - if ((t = x >> 1) != 0) { - x = t; - n += 1; - } - return n; -} - -function bnToMPI () { - var ba = this.toByteArray(); - var size = (ba.length-1)*8+nbits(ba[0]); - var result = ""; - result += String.fromCharCode((size & 0xFF00) >> 8); - result += String.fromCharCode(size & 0xFF); - result += util.bin2str(ba); - return result; -} -/* END of addition */ - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; -BigInteger.prototype.toMPI = bnToMPI; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// ElGamal implementation - -function Elgamal() { - - function encrypt(m,g,p,y) { - // choose k in {2,...,p-2} - var two = BigInteger.ONE.add(BigInteger.ONE); - var pMinus2 = p.subtract(two); - var k = openpgp_crypto_getRandomBigIntegerInRange(two, pMinus2); - var k = k.mod(pMinus2).add(BigInteger.ONE); - var c = new Array(); - c[0] = g.modPow(k, p); - c[1] = y.modPow(k, p).multiply(m).mod(p).toMPI(); - c[0] = c[0].toMPI(); - return c; - } - - function decrypt(c1,c2,p,x) { - util.print_debug("Elgamal Decrypt:\nc1:"+util.hexstrdump(c1.toMPI())+"\n"+ - "c2:"+util.hexstrdump(c2.toMPI())+"\n"+ - "p:"+util.hexstrdump(p.toMPI())+"\n"+ - "x:"+util.hexstrdump(x.toMPI())); - return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p); - //var c = c1.pow(x).modInverse(p); // c0^-a mod p - //return c.multiply(c2).mod(p); - } - - // signing and signature verification using Elgamal is not required by OpenPGP. - this.encrypt = encrypt; - this.decrypt = decrypt; -}// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// A Digital signature algorithm implementation - -function DSA() { - // s1 = ((g**s) mod p) mod q - // s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q) - function sign(hashalgo, m, g, p, q, x) { - // If the output size of the chosen hash is larger than the number of - // bits of q, the hash result is truncated to fit by taking the number - // of leftmost bits equal to the number of bits of q. This (possibly - // truncated) hash function result is treated as a number and used - // directly in the DSA signature algorithm. - var hashed_data = util.getLeftNBits(openpgp_crypto_hashData(hashalgo,m),q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - var k = openpgp_crypto_getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); - var s1 = (g.modPow(k,p)).mod(q); - var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); - var result = new Array(); - result[0] = s1.toMPI(); - result[1] = s2.toMPI(); - return result; - } - function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; - /* - * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - */ - switch (Math.round(q.bitLength() / 8)) { - case 20: // 1024 bit - if (usersetting != 2 && - usersetting > 11 && - usersetting != 10 && - usersetting < 8) - return 2; // prefer sha1 - return usersetting; - case 28: // 2048 bit - if (usersetting > 11 && - usersetting < 8) - return 11; - return usersetting; - case 32: // 4096 bit // prefer sha224 - if (usersetting > 10 && - usersetting < 8) - return 8; // prefer sha256 - return usersetting; - default: - util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"); - return null; - - } - } - this.select_hash_algorithm = select_hash_algorithm; - - function verify(hashalgo, s1,s2,m,p,q,g,y) { - var hashed_data = util.getLeftNBits(openpgp_crypto_hashData(hashalgo,m),q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - if (BigInteger.ZERO.compareTo(s1) > 0 || - s1.compareTo(q) > 0 || - BigInteger.ZERO.compareTo(s2) > 0 || - s2.compareTo(q) > 0) { - util.print_error("invalid DSA Signature"); - return null; - } - var w = s2.modInverse(q); - var u1 = hash.multiply(w).mod(q); - var u2 = s1.multiply(w).mod(q); - return g.modPow(u1,p).multiply(y.modPow(u2,p)).mod(p).mod(q); - } - - /* - * unused code. This can be used as a start to write a key generator - * function. - - function generateKey(bitcount) { - var qi = new BigInteger(bitcount, primeCenterie); - var pi = generateP(q, 512); - var gi = generateG(p, q, bitcount); - var xi; - do { - xi = new BigInteger(q.bitCount(), rand); - } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1); - var yi = g.modPow(x, p); - return {x: xi, q: qi, p: pi, g: gi, y: yi}; - } - - function generateP(q, bitlength, randomfn) { - if (bitlength % 64 != 0) { - return false; - } - var pTemp; - var pTemp2; - do { - pTemp = randomfn(bitcount, true); - pTemp2 = pTemp.subtract(BigInteger.ONE); - pTemp = pTemp.subtract(pTemp2.remainder(q)); - } while (!pTemp.isProbablePrime(primeCenterie) || pTemp.bitLength() != l); - return pTemp; - } - - function generateG(p, q, bitlength, randomfn) { - var aux = p.subtract(BigInteger.ONE); - var pow = aux.divide(q); - var gTemp; - do { - gTemp = randomfn(bitlength); - } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1); - return gTemp.modPow(pow, p); - } - - function generateK(q, bitlength, randomfn) { - var tempK; - do { - tempK = randomfn(bitlength, false); - } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1); - return tempK; - } - - function generateR(q,p) { - k = generateK(q); - var r = g.modPow(k, p).mod(q); - return r; - } - - function generateS(hashfn,k,r,m,q,x) { - var hash = hashfn(m); - s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q); - return s; - } */ - this.sign = sign; - this.verify = verify; - // this.generate = generateKey; -} -//Paul Tero, July 2001 -//http://www.tero.co.uk/des/ -// -//Optimised for performance with large blocks by Michael Hayworth, November 2001 -//http://www.netdealing.com -// -// Modified by Recurity Labs GmbH - -//THIS SOFTWARE IS PROVIDED "AS IS" AND -//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -//SUCH DAMAGE. - -//des -//this takes the key, the message, and whether to encrypt or decrypt - -// added by Recurity Labs -function desede(block,key) { - var key1 = key.substring(0,8); - var key2 = key.substring(8,16); - var key3 = key.substring(16,24); - return util.str2bin(des(des_createKeys(key3),des(des_createKeys(key2),des(des_createKeys(key1),util.bin2str(block), true, 0,null,null), false, 0,null,null), true, 0,null,null)); -} - - -function des (keys, message, encrypt, mode, iv, padding) { - //declaring this locally speeds things up a bit - var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004); - var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000); - var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200); - var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080); - var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100); - var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010); - var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002); - var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000); - - //create the 16 or 48 subkeys we will need - var m=0, i, j, temp, temp2, right1, right2, left, right, looping; - var cbcleft, cbcleft2, cbcright, cbcright2 - var endloop, loopinc; - var len = message.length; - var chunk = 0; - //set up the loops for single and triple des - var iterations = keys.length == 32 ? 3 : 9; //single or triple des - if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);} - else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);} - - //pad the message depending on the padding parameter - if (padding == 2) message += " "; //pad the message with spaces - else if (padding == 1) {temp = 8-(len%8); message += String.fromCharCode (temp,temp,temp,temp,temp,temp,temp,temp); if (temp==8) len+=8;} //PKCS7 padding - else if (!padding) message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes - - //store the result here - result = ""; - tempresult = ""; - - if (mode == 1) { //CBC mode - cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - m=0; - } - - //loop through each 64 bit chunk of the message - while (m < len) { - left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); - right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}} - - //first each 64 but chunk of the message must be permuted according to IP - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - - left = ((left << 1) | (left >>> 31)); - right = ((right << 1) | (right >>> 31)); - - //do this either 1 or 3 times for each chunk of the message - for (j=0; j>> 4) | (right << 28)) ^ keys[i+1]; - //the result is attained by passing these bytes through the S selection functions - temp = left; - left = right; - right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] - | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] - | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] - | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); - } - temp = left; left = right; right = temp; //unreverse left and right - } //for either 1 or 3 iterations - - //move then each one bit to the right - left = ((left >>> 1) | (left << 31)); - right = ((right >>> 1) | (right << 31)); - - //now perform IP-1, which is IP in the opposite direction - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - - //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}} - tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff)); - - chunk += 8; - if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;} - } //for every 8 characters, or 64 bits in the message - - //return the result as an array - result += tempresult; - result = result.replace(/\0*$/g, ""); - return result; -} //end of des - - - -//des_createKeys -//this takes as input a 64 bit key (even though only 56 bits are used) -//as an array of 2 integers, and returns 16 48 bit keys -function des_createKeys (key) { - //declaring this locally speeds things up a bit - pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204); - pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101); - pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808); - pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000); - pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010); - pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420); - pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002); - pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800); - pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002); - pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408); - pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020); - pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200); - pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010); - pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105); - - //how many iterations (1 for des, 3 for triple des) - var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys - //stores the return keys - var keys = new Array (32 * iterations); - //now define the left shifts which need to be done - var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); - //other variables - var lefttemp, righttemp, m=0, n=0, temp; - - for (var j=0; j>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - - //the right side needs to be shifted and to get the last four bits of the left side - temp = (left << 8) | ((right >>> 20) & 0x000000f0); - //left needs to be put upside down - left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); - right = temp; - - //now go through and perform these shifts on the left and right keys - for (i=0; i < shifts.length; i++) { - //shift the keys either one or two bits to the left - if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);} - else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);} - left &= -0xf; right &= -0xf; - - //now apply PC-2, in such a way that E is easier when encrypting or decrypting - //this conversion will look like PC-2 except only the last 6 bits of each byte are used - //rather than 48 consecutive bits and the order of lines will be according to - //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] - | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] - | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] - | pc2bytes6[(left >>> 4) & 0xf]; - righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] - | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] - | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] - | pc2bytes13[(right >>> 4) & 0xf]; - temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; - keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16); - } - } //for each iterations - //return the keys we've created - return keys; -} //end of des_createKeys - - - -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Copyright 2010 pjacobs@xeekr.com . All rights reserved. - -// Modified by Recurity Labs GmbH - -// fixed/modified by Herbert Hanewinkel, www.haneWIN.de -// check www.haneWIN.de for the latest version - -// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144. -// CAST-128 is a common OpenPGP cipher. - - -// CAST5 constructor - -function cast5_encrypt(block, key) { - var cast5 = new openpgp_symenc_cast5(); - cast5.setKey(util.str2bin(key)); - return cast5.encrypt(block); -} - -function openpgp_symenc_cast5() { - this.BlockSize= 8; - this.KeySize = 16; - - this.setKey = function (key) { - this.masking = new Array(16); - this.rotate = new Array(16); - - this.reset(); - - if (key.length == this.KeySize) - { - this.keySchedule(key); - } - else - { - util.print_error('cast5.js: CAST-128: keys must be 16 bytes'); - return false; - } - return true; - }; - - this.reset = function() { - for (var i = 0; i < 16; i++) - { - this.masking[i] = 0; - this.rotate[i] = 0; - } - }; - - this.getBlockSize = function() { - return BlockSize; - }; - - this.encrypt = function(src) { - var dst = new Array(src.length); - - for(i = 0; i < src.length; i+=8) - { - var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; - var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; - var t; - - t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; - t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; - t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; - t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; - - t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; - t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; - t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; - t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; - - t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; - t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; - t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; - t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; - - t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; - t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; - t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; - t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; - - dst[i] = (r >>> 24)&255; - dst[i+1] = (r >>> 16)&255; - dst[i+2] = (r >>> 8)&255; - dst[i+3] = r&255; - dst[i+4] = (l >>> 24)&255; - dst[i+5] = (l >>> 16)&255; - dst[i+6] = (l >>> 8)&255; - dst[i+7] = l&255; - } - - return dst; - }; - - this.decrypt = function(src) { - var dst = new Array(src.length); - - for(i = 0; i < src.length; i+=8) - { - var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; - var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; - var t; - - t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; - t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; - t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; - t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; - - t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; - t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; - t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; - t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; - - t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; - t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; - t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; - t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; - - t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; - t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; - t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; - t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; - - dst[i] = (r >>> 24)&255; - dst[i+1] = (r >>> 16)&255; - dst[i+2] = (r >>> 8)&255; - dst[i+3] = r&255; - dst[i+4] = (l >>> 24)&255; - dst[i+5] = (l >> 16)&255; - dst[i+6] = (l >> 8)&255; - dst[i+7] = l&255; - } - - return dst; - }; - var scheduleA = new Array(4); - - scheduleA[0] = new Array(4); - scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8); - scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - scheduleA[1] = new Array(4); - scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - scheduleA[2] = new Array(4); - scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8); - scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - - scheduleA[3] = new Array(4); - scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - var scheduleB = new Array(4); - - scheduleB[0] = new Array(4); - scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2); - scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6); - scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9); - scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc); - - scheduleB[1] = new Array(4); - scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8); - scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd); - scheduleB[1][2] = new Array(7, 6, 8, 9, 3); - scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7); - - - scheduleB[2] = new Array(4); - scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9); - scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc); - scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2); - scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6); - - - scheduleB[3] = new Array(4); - scheduleB[3][0] = new Array(8, 9, 7, 6, 3); - scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7); - scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8); - scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd); - - // changed 'in' to 'inn' (in javascript 'in' is a reserved word) - this.keySchedule = function(inn) - { - var t = new Array(8); - var k = new Array(32); - - for (var i = 0; i < 4; i++) - { - var j = i * 4; - t[i] = inn[j]<<24 | inn[j+1]<<16 | inn[j+2]<<8 | inn[j+3]; - } - - var x = [6, 7, 4, 5]; - var ki = 0; - - for (var half = 0; half < 2; half++) - { - for (var round = 0; round < 4; round++) - { - for (var j = 0; j < 4; j++) - { - var a = scheduleA[round][j]; - var w = t[a[1]]; - - w ^= sBox[4][(t[a[2]>>>2]>>>(24-8*(a[2]&3)))&0xff]; - w ^= sBox[5][(t[a[3]>>>2]>>>(24-8*(a[3]&3)))&0xff]; - w ^= sBox[6][(t[a[4]>>>2]>>>(24-8*(a[4]&3)))&0xff]; - w ^= sBox[7][(t[a[5]>>>2]>>>(24-8*(a[5]&3)))&0xff]; - w ^= sBox[x[j]][(t[a[6]>>>2]>>>(24-8*(a[6]&3)))&0xff]; - t[a[0]] = w; - } - - for (var j = 0; j < 4; j++) - { - var b = scheduleB[round][j]; - var w = sBox[4][(t[b[0]>>>2]>>>(24-8*(b[0]&3)))&0xff]; - - w ^= sBox[5][(t[b[1]>>>2]>>>(24-8*(b[1]&3)))&0xff]; - w ^= sBox[6][(t[b[2]>>>2]>>>(24-8*(b[2]&3)))&0xff]; - w ^= sBox[7][(t[b[3]>>>2]>>>(24-8*(b[3]&3)))&0xff]; - w ^= sBox[4+j][(t[b[4]>>>2]>>>(24-8*(b[4]&3)))&0xff]; - k[ki] = w; - ki++; - } - } - } - - for (var i = 0; i < 16; i++) - { - this.masking[i] = k[i]; - this.rotate[i] = k[16+i] & 0x1f; - } - }; - - // These are the three 'f' functions. See RFC 2144, section 2.2. - - function f1(d, m, r) - { - var t = m + d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] ^ sBox[1][(I>>>16)&255]) - sBox[2][(I>>>8)&255]) + sBox[3][I&255]; - } - - function f2(d, m, r) - { - var t = m ^ d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] - sBox[1][(I>>>16)&255]) + sBox[2][(I>>>8)&255]) ^ sBox[3][I&255]; - } - - function f3(d, m, r) - { - var t = m - d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] + sBox[1][(I>>>16)&255]) ^ sBox[2][(I>>>8)&255]) - sBox[3][I&255]; - } - - var sBox = new Array(8); - sBox[0] = new Array( - 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, - 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, - 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, - 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, - 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, - 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, - 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, - 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, - 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, - 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, - 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, - 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, - 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, - 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, - 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, - 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, - 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, - 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, - 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, - 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, - 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, - 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, - 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, - 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, - 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, - 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, - 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, - 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, - 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, - 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, - 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, - 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf); - - sBox[1] = new Array( - 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, - 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, - 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, - 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, - 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, - 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, - 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, - 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, - 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, - 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, - 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, - 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, - 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, - 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, - 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, - 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, - 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, - 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, - 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, - 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, - 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, - 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, - 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, - 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, - 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, - 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, - 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, - 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, - 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, - 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, - 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, - 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1); - - sBox[2] = new Array( - 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, - 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, - 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, - 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, - 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, - 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, - 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, - 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, - 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, - 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, - 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, - 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, - 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, - 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, - 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, - 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, - 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, - 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, - 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, - 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, - 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, - 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, - 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, - 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, - 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, - 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, - 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, - 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, - 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, - 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, - 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, - 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783); - - sBox[3] = new Array( - 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, - 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, - 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, - 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, - 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, - 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, - 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, - 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, - 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, - 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, - 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, - 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, - 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, - 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, - 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, - 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, - 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, - 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, - 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, - 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, - 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, - 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, - 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, - 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, - 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, - 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, - 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, - 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, - 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, - 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, - 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, - 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2); - - sBox[4] = new Array( - 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, - 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, - 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, - 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, - 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, - 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, - 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, - 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, - 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, - 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, - 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, - 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, - 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, - 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, - 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, - 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, - 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, - 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, - 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, - 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, - 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, - 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, - 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, - 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, - 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, - 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, - 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, - 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, - 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, - 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, - 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, - 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4); - - sBox[5] = new Array( - 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, - 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, - 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, - 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, - 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, - 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, - 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, - 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, - 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, - 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, - 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, - 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, - 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, - 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, - 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, - 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, - 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, - 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, - 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, - 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, - 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, - 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, - 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, - 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, - 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, - 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, - 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, - 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, - 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, - 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, - 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, - 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f); - - sBox[6] = new Array( - 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, - 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, - 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, - 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, - 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, - 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, - 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, - 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, - 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, - 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, - 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, - 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, - 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, - 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, - 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, - 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, - 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, - 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, - 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, - 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, - 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, - 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, - 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, - 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, - 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, - 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, - 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, - 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, - 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, - 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, - 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, - 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3); - - sBox[7] = new Array( - 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, - 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, - 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, - 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, - 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, - 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, - 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, - 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, - 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, - 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, - 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, - 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, - 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, - 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, - 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, - 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, - 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, - 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, - 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, - 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, - 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, - 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, - 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, - 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, - 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, - 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, - 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, - 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, - 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, - 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, - 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, - 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e); - -}; - -/* Modified by Recurity Labs GmbH - * - * Cipher.js - * A block-cipher algorithm implementation on JavaScript - * See Cipher.readme.txt for further information. - * - * Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ] - * This script file is distributed under the LGPL - * - * ACKNOWLEDGMENT - * - * The main subroutines are written by Michiel van Everdingen. - * - * Michiel van Everdingen - * http://home.versatel.nl/MAvanEverdingen/index.html - * - * All rights for these routines are reserved to Michiel van Everdingen. - * - */ - -// added by Recurity Labs -function TFencrypt(block, key) { - var block_copy = [].concat(block); - var tf = createTwofish(); - tf.open(util.str2bin(key),0); - var result = tf.encrypt(block_copy, 0); - tf.close(); - return result; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Math -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -var MAXINT = 0xFFFFFFFF; - -function rotb(b,n){ return ( b<>>( 8-n) ) & 0xFF; } -function rotw(w,n){ return ( w<>>(32-n) ) & MAXINT; } -function getW(a,i){ return a[i]|a[i+1]<<8|a[i+2]<<16|a[i+3]<<24; } -function setW(a,i,w){ a.splice(i,4,w&0xFF,(w>>>8)&0xFF,(w>>>16)&0xFF,(w>>>24)&0xFF); } -function setWInv(a,i,w){ a.splice(i,4,(w>>>24)&0xFF,(w>>>16)&0xFF,(w>>>8)&0xFF,w&0xFF); } -function getB(x,n){ return (x>>>(n*8))&0xFF; } - -function getNrBits(i){ var n=0; while (i>0){ n++; i>>>=1; } return n; } -function getMask(n){ return (1<> 2) ^ [ 0, 90, 180, 238 ][x & 3]; - } - function ffmEf(x) { - return x ^ (x >> 1) ^ (x >> 2) ^ [ 0, 238, 180, 90 ][x & 3]; - } - - function mdsRem(p, q) { - var i, t, u; - for (i = 0; i < 8; i++) { - t = q >>> 24; - q = ((q << 8) & MAXINT) | p >>> 24; - p = (p << 8) & MAXINT; - u = t << 1; - if (t & 128) { - u ^= 333; - } - q ^= t ^ (u << 16); - u ^= t >>> 1; - if (t & 1) { - u ^= 166; - } - q ^= u << 24 | u << 8; - } - return q; - } - - function qp(n, x) { - var a, b, c, d; - a = x >> 4; - b = x & 15; - c = q0[n][a ^ b]; - d = q1[n][ror4[b] ^ ashx[a]]; - return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; - } - - function hFun(x, key) { - var a = getB(x, 0), b = getB(x, 1), c = getB(x, 2), d = getB(x, 3); - switch (kLen) { - case 4: - a = q[1][a] ^ getB(key[3], 0); - b = q[0][b] ^ getB(key[3], 1); - c = q[0][c] ^ getB(key[3], 2); - d = q[1][d] ^ getB(key[3], 3); - case 3: - a = q[1][a] ^ getB(key[2], 0); - b = q[1][b] ^ getB(key[2], 1); - c = q[0][c] ^ getB(key[2], 2); - d = q[0][d] ^ getB(key[2], 3); - case 2: - a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); - b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); - c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2); - d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3); - } - return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d]; - } - - keyBytes = keyBytes.slice(0, 32); - i = keyBytes.length; - while (i != 16 && i != 24 && i != 32) - keyBytes[i++] = 0; - - for (i = 0; i < keyBytes.length; i += 4) { - inKey[i >> 2] = getW(keyBytes, i); - } - for (i = 0; i < 256; i++) { - q[0][i] = qp(0, i); - q[1][i] = qp(1, i); - } - for (i = 0; i < 256; i++) { - f01 = q[1][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); - m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); - f01 = q[0][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); - m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); - } - - kLen = inKey.length / 2; - for (i = 0; i < kLen; i++) { - a = inKey[i + i]; - meKey[i] = a; - b = inKey[i + i + 1]; - moKey[i] = b; - sKey[kLen - i - 1] = mdsRem(a, b); - } - for (i = 0; i < 40; i += 2) { - a = 0x1010101 * i; - b = a + 0x1010101; - a = hFun(a, meKey); - b = rotw(hFun(b, moKey), 8); - tfsKey[i] = (a + b) & MAXINT; - tfsKey[i + 1] = rotw(a + 2 * b, 9); - } - for (i = 0; i < 256; i++) { - a = b = c = d = i; - switch (kLen) { - case 4: - a = q[1][a] ^ getB(sKey[3], 0); - b = q[0][b] ^ getB(sKey[3], 1); - c = q[0][c] ^ getB(sKey[3], 2); - d = q[1][d] ^ getB(sKey[3], 3); - case 3: - a = q[1][a] ^ getB(sKey[2], 0); - b = q[1][b] ^ getB(sKey[2], 1); - c = q[0][c] ^ getB(sKey[2], 2); - d = q[0][d] ^ getB(sKey[2], 3); - case 2: - tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] - ^ getB(sKey[0], 0)]; - tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] - ^ getB(sKey[0], 1)]; - tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] - ^ getB(sKey[0], 2)]; - tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] - ^ getB(sKey[0], 3)]; - } - } - } - - function tfsG0(x) { - return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] - ^ tfsM[3][getB(x, 3)]; - } - function tfsG1(x) { - return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] - ^ tfsM[3][getB(x, 2)]; - } - - function tfsFrnd(r, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); - blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); - blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; - } - - function tfsIrnd(i, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; - blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; - blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); - } - - function tfsClose() { - tfsKey = []; - tfsM = [ [], [], [], [] ]; - } - - function tfsEncrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[0], - getW(dataBytes, dataOffset + 4) ^ tfsKey[1], - getW(dataBytes, dataOffset + 8) ^ tfsKey[2], - getW(dataBytes, dataOffset + 12) ^ tfsKey[3] ]; - for ( var j = 0; j < 8; j++) { - tfsFrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]); - dataOffset += 16; - return dataBytes; - } - - function tfsDecrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[4], - getW(dataBytes, dataOffset + 4) ^ tfsKey[5], - getW(dataBytes, dataOffset + 8) ^ tfsKey[6], - getW(dataBytes, dataOffset + 12) ^ tfsKey[7] ]; - for ( var j = 7; j >= 0; j--) { - tfsIrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]); - dataOffset += 16; - } - - // added by Recurity Labs - function tfsFinal() { - return dataBytes; - } - - return { - name : "twofish", - blocksize : 128 / 8, - open : tfsInit, - close : tfsClose, - encrypt : tfsEncrypt, - decrypt : tfsDecrypt, - // added by Recurity Labs - finalize: tfsFinal - }; -} - -/* Modified by Recurity Labs GmbH - * - * Originally written by nklein software (nklein.com) - */ - -/* - * Javascript implementation based on Bruce Schneier's reference implementation. - * - * - * The constructor doesn't do much of anything. It's just here - * so we can start defining properties and methods and such. - */ -function Blowfish() { -}; - -/* - * Declare the block size so that protocols know what size - * Initialization Vector (IV) they will need. - */ -Blowfish.prototype.BLOCKSIZE = 8; - -/* - * These are the default SBOXES. - */ -Blowfish.prototype.SBOXES = [ - [ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, - 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, - 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, - 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, - 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, - 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, - 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, - 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, - 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, - 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, - 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, - 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, - 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, - 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, - 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, - 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, - 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, - 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ], [ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, - 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, - 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, - 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, - 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, - 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, - 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, - 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, - 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, - 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, - 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, - 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, - 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, - 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, - 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, - 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, - 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, - 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ], [ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, - 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, - 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, - 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, - 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, - 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, - 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, - 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, - 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, - 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, - 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, - 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, - 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, - 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, - 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, - 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, - 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, - 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ], [ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, - 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, - 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, - 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, - 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, - 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, - 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, - 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, - 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, - 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, - 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, - 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, - 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, - 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, - 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, - 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, - 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, - 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ] -]; - -//* -//* This is the default PARRAY -//* -Blowfish.prototype.PARRAY = [ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b -]; - -//* -//* This is the number of rounds the cipher will go -//* -Blowfish.prototype.NN = 16; - -//* -//* This function is needed to get rid of problems -//* with the high-bit getting set. If we don't do -//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not -//* equal to ( bb & 0x00FFFFFFFF ) even when they -//* agree bit-for-bit for the first 32 bits. -//* -Blowfish.prototype._clean = function( xx ) { - if ( xx < 0 ) { - var yy = xx & 0x7FFFFFFF; - xx = yy + 0x80000000; - } - return xx; -}; - -//* -//* This is the mixing function that uses the sboxes -//* -Blowfish.prototype._F = function ( xx ) { - var aa; - var bb; - var cc; - var dd; - var yy; - - dd = xx & 0x00FF; - xx >>>= 8; - cc = xx & 0x00FF; - xx >>>= 8; - bb = xx & 0x00FF; - xx >>>= 8; - aa = xx & 0x00FF; - - yy = this.sboxes[ 0 ][ aa ] + this.sboxes[ 1 ][ bb ]; - yy = yy ^ this.sboxes[ 2 ][ cc ]; - yy = yy + this.sboxes[ 3 ][ dd ]; - - return yy; -}; - -//* -//* This method takes an array with two values, left and right -//* and does NN rounds of Blowfish on them. -//* -Blowfish.prototype._encrypt_block = function ( vals ) { - var dataL = vals[ 0 ]; - var dataR = vals[ 1 ]; - - var ii; - - for ( ii=0; ii < this.NN; ++ii ) { - dataL = dataL ^ this.parray[ ii ]; - dataR = this._F( dataL ) ^ dataR; - - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } - - dataL = dataL ^ this.parray[ this.NN + 0 ]; - dataR = dataR ^ this.parray[ this.NN + 1 ]; - - vals[ 0 ] = this._clean( dataR ); - vals[ 1 ] = this._clean( dataL ); -}; - -//* -//* This method takes a vector of numbers and turns them -//* into long words so that they can be processed by the -//* real algorithm. -//* -//* Maybe I should make the real algorithm above take a vector -//* instead. That will involve more looping, but it won't require -//* the F() method to deconstruct the vector. -//* -Blowfish.prototype.encrypt_block = function ( vector ) { - var ii; - var vals = [ 0, 0 ]; - var off = this.BLOCKSIZE/2; - for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { - vals[0] = ( vals[0] << 8 ) | ( vector[ ii + 0 ] & 0x00FF ); - vals[1] = ( vals[1] << 8 ) | ( vector[ ii + off ] & 0x00FF ); - } - - this._encrypt_block( vals ); - - var ret = [ ]; - for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { - ret[ ii + 0 ] = ( vals[ 0 ] >>> (24 - 8*(ii)) & 0x00FF ); - ret[ ii + off ] = ( vals[ 1 ] >>> (24 - 8*(ii)) & 0x00FF ); - // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); - // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); - } - - return ret; -}; - -//* -//* This method takes an array with two values, left and right -//* and undoes NN rounds of Blowfish on them. -//* -Blowfish.prototype._decrypt_block = function ( vals ) { - var dataL = vals[ 0 ]; - var dataR = vals[ 1 ]; - - var ii; - - for ( ii=this.NN+1; ii > 1; --ii ) { - dataL = dataL ^ this.parray[ ii ]; - dataR = this._F( dataL ) ^ dataR; - - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } - - dataL = dataL ^ this.parray[ 1 ]; - dataR = dataR ^ this.parray[ 0 ]; - - vals[ 0 ] = this._clean( dataR ); - vals[ 1 ] = this._clean( dataL ); -}; - -//* -//* This method takes a key array and initializes the -//* sboxes and parray for this encryption. -//* -Blowfish.prototype.init = function ( key ) { - var ii; - var jj = 0; - - this.parray = []; - for ( ii=0; ii < this.NN + 2; ++ii ) { - var data = 0x00000000; - var kk; - for ( kk=0; kk < 4; ++kk ) { - data = ( data << 8 ) | ( key[ jj ] & 0x00FF ); - if ( ++jj >= key.length ) { - jj = 0; - } - } - this.parray[ ii ] = this.PARRAY[ ii ] ^ data; - } - - this.sboxes = []; - for ( ii=0; ii < 4; ++ii ) { - this.sboxes[ ii ] = []; - for ( jj=0; jj < 256; ++jj ) { - this.sboxes[ ii ][ jj ] = this.SBOXES[ ii ][ jj ]; - } - } - - var vals = [ 0x00000000, 0x00000000 ]; - - for ( ii=0; ii < this.NN+2; ii += 2 ) { - this._encrypt_block( vals ); - this.parray[ ii + 0 ] = vals[ 0 ]; - this.parray[ ii + 1 ] = vals[ 1 ]; - } - - for ( ii=0; ii < 4; ++ii ) { - for ( jj=0; jj < 256; jj += 2 ) { - this._encrypt_block( vals ); - this.sboxes[ ii ][ jj + 0 ] = vals[ 0 ]; - this.sboxes[ ii ][ jj + 1 ] = vals[ 1 ]; - } - } -}; - -// added by Recurity Labs -function BFencrypt(block,key) { - var bf = new Blowfish(); - bf.init(util.str2bin(key)); - return bf.encrypt_block(block); -} - -/* Rijndael (AES) Encryption - * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de - * version 1.1, check www.haneWIN.de for the latest version - - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other - * materials provided with the application or distribution. - */ - -// The round constants used in subkey expansion -var Rcon = [ -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 ]; - -// Precomputed lookup table for the SBox -var S = [ - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, -118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, -114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, -216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, -235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, -179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, -190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, -249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, -188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, -23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, -144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, - 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, -141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, - 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, -181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, -248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, -140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, - 22 ]; - -var T1 = [ -0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, -0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, -0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, -0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, -0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, -0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, -0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, -0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, -0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, -0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, -0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, -0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, -0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, -0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, -0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, -0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, -0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, -0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, -0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, -0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, -0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, -0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, -0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, -0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, -0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, -0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, -0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, -0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, -0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, -0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, -0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, -0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, -0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, -0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, -0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, -0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, -0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, -0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, -0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, -0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, -0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, -0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, -0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, -0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, -0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, -0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, -0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, -0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, -0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, -0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, -0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, -0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, -0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, -0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, -0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, -0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, -0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, -0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, -0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, -0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, -0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, -0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, -0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, -0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c ]; - -var T2 = [ -0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, -0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, -0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, -0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, -0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, -0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, -0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, -0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, -0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, -0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, -0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, -0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, -0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, -0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, -0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, -0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, -0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, -0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, -0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, -0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, -0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, -0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, -0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, -0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, -0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, -0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, -0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, -0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, -0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, -0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, -0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, -0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, -0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, -0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, -0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, -0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, -0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, -0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, -0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, -0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, -0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, -0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, -0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, -0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, -0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, -0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, -0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, -0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, -0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, -0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, -0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, -0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, -0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, -0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, -0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, -0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, -0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, -0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, -0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, -0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, -0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, -0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, -0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, -0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a ]; - -var T3 = [ -0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, -0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, -0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, -0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, -0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, -0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, -0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, -0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, -0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, -0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, -0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, -0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, -0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, -0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, -0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, -0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, -0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, -0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, -0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, -0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, -0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, -0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, -0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, -0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, -0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, -0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, -0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, -0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, -0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, -0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, -0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, -0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, -0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, -0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, -0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, -0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, -0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, -0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, -0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, -0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, -0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, -0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, -0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, -0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, -0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, -0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, -0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, -0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, -0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, -0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, -0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, -0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, -0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, -0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, -0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, -0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, -0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, -0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, -0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, -0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, -0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, -0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, -0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, -0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 ]; - -var T4 = [ -0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, -0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, -0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, -0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, -0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, -0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, -0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, -0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, -0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, -0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, -0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, -0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, -0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, -0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, -0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, -0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, -0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, -0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, -0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, -0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, -0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, -0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, -0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, -0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, -0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, -0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, -0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, -0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, -0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, -0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, -0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, -0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, -0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, -0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, -0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, -0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, -0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, -0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, -0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, -0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, -0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, -0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, -0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, -0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, -0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, -0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, -0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, -0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, -0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, -0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, -0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, -0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, -0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, -0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, -0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, -0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, -0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, -0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, -0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, -0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, -0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, -0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, -0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, -0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 ]; -function B0(x) { return (x&255); } -function B1(x) { return ((x>>8)&255); } -function B2(x) { return ((x>>16)&255); } -function B3(x) { return ((x>>24)&255); } +var hex_chr = '0123456789abcdef'.split(''); -function F1(x0, x1, x2, x3) +function rhex(n) { - return B1(T1[x0&255]) | (B1(T1[(x1>>8)&255])<<8) - | (B1(T1[(x2>>16)&255])<<16) | (B1(T1[x3>>>24])<<24); +var s='', j=0; +for(; j<4; j++) +s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] ++ hex_chr[(n >> (j * 8)) & 0x0F]; +return s; } -function packBytes(octets) -{ - var i, j; - var len=octets.length; - var b=new Array(len/4); - - if (!octets || len % 4) return; - - for (i=0, j=0; j=0; j--) tk[j] = k[j]; - - r=0; - t=0; - for(j=0; (j>8)&255] ^ T3[(t2>>16)&255] ^ T4[t3>>>24]; - b1 = T1[t1&255] ^ T2[(t2>>8)&255] ^ T3[(t3>>16)&255] ^ T4[t0>>>24]; - b2 = T1[t2&255] ^ T2[(t3>>8)&255] ^ T3[(t0>>16)&255] ^ T4[t1>>>24]; - b3 = T1[t3&255] ^ T2[(t0>>8)&255] ^ T3[(t1>>16)&255] ^ T4[t2>>>24]; - } - - // last round is special - r = rounds-1; - - t0 = b0 ^ ctx.rk[r][0]; - t1 = b1 ^ ctx.rk[r][1]; - t2 = b2 ^ ctx.rk[r][2]; - t3 = b3 ^ ctx.rk[r][3]; - - b[0] = F1(t0, t1, t2, t3) ^ ctx.rk[rounds][0]; - b[1] = F1(t1, t2, t3, t0) ^ ctx.rk[rounds][1]; - b[2] = F1(t2, t3, t0, t1) ^ ctx.rk[rounds][2]; - b[3] = F1(t3, t0, t1, t2) ^ ctx.rk[rounds][3]; - - return unpackBytes(b); +if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { +function add32(x, y) { +var lsw = (x & 0xFFFF) + (y & 0xFFFF), +msw = (x >> 16) + (y >> 16) + (lsw >> 16); +return (msw << 16) | (lsw & 0xFFFF); } -// Modified by Recurity Labs GmbH - -// modified version of http://www.hanewin.net/encrypt/PGdecode.js: - -/* OpenPGP encryption using RSA/AES - * Copyright 2005-2006 Herbert Hanewinkel, www.haneWIN.de - * version 2.0, check www.haneWIN.de for the latest version - - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other - * materials provided with the application or distribution. - */ - -// -------------------------------------- -/** - * This function encrypts a given with the specified prefixrandom - * using the specified blockcipher to encrypt a message - * @param prefixrandom random bytes of block_size length provided - * as a string to be used in prefixing the data - * @param blockcipherfn the algorithm encrypt function to encrypt - * data in one block_size encryption. The function must be - * specified as blockcipherfn([integer_array(integers 0..255)] - * block,[integer_array(integers 0..255)] key) returning an - * array of bytes (integers 0..255) - * @param block_size the block size in bytes of the algorithm used - * @param plaintext data to be encrypted provided as a string - * @param key key to be used to encrypt the data as - * integer_array(integers 0..255)]. This will be passed to the - * blockcipherfn - * @param resync a boolean value specifying if a resync of the - * IV should be used or not. The encrypteddatapacket uses the - * "old" style with a resync. Encryption within an - * encryptedintegrityprotecteddata packet is not resyncing the IV. - * @return a string with the encrypted data - */ -function openpgp_cfb_encrypt(prefixrandom, blockcipherencryptfn, plaintext, block_size, key, resync) { - var FR = new Array(block_size); - var FRE = new Array(block_size); - - prefixrandom = prefixrandom + prefixrandom.charAt(block_size-2) +prefixrandom.charAt(block_size-1); - util.print_debug("prefixrandom:"+util.hexstrdump(prefixrandom)); - var ciphertext = ""; - // 1. The feedback register (FR) is set to the IV, which is all zeros. - for (var i = 0; i < block_size; i++) FR[i] = 0; - - // 2. FR is encrypted to produce FRE (FR Encrypted). This is the - // encryption of an all-zero value. - FRE = blockcipherencryptfn(FR, key); - // 3. FRE is xored with the first BS octets of random data prefixed to - // the plaintext to produce C[1] through C[BS], the first BS octets - // of ciphertext. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ prefixrandom.charCodeAt(i)); - - // 4. FR is loaded with C[1] through C[BS]. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - - // 5. FR is encrypted to produce FRE, the encryption of the first BS - // octets of ciphertext. - FRE = blockcipherencryptfn(FR, key); - - // 6. The left two octets of FRE get xored with the next two octets of - // data that were prefixed to the plaintext. This produces C[BS+1] - // and C[BS+2], the next two octets of ciphertext. - ciphertext += String.fromCharCode(FRE[0] ^ prefixrandom.charCodeAt(block_size)); - ciphertext += String.fromCharCode(FRE[1] ^ prefixrandom.charCodeAt(block_size+1)); - - if (resync) { - // 7. (The resync step) FR is loaded with C3-C10. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i+2); - } else { - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - } - // 8. FR is encrypted to produce FRE. - FRE = blockcipherencryptfn(FR, key); - - if (resync) { - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 0; i < block_size; i++) - ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - for(n=block_size+2; n < plaintext.length; n+=block_size) { - // 10. FR is loaded with C11-C18 - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(n+i); - - // 11. FR is encrypted to produce FRE. - FRE = blockcipherencryptfn(FR, key); - - // 12. FRE is xored with the next 8 octets of plaintext, to produce the - // next 8 octets of ciphertext. These are loaded into FR and the - // process is repeated until the plaintext is used up. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt((n-2)+i)); - } - } - else { - plaintext = " "+plaintext; - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 2; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - var tempCiphertext = ciphertext.substring(0,2*block_size).split(''); - var tempCiphertextString = ciphertext.substring(block_size); - for(n=block_size; n block_size*pos) { - var encblock = blockcipherencryptfn(blockc, key); - blocki = plaintext.substring((pos*block_size),(pos*block_size)+block_size); - for (var i=0; i < blocki.length; i++) - tempBlock.push(String.fromCharCode(blocki.charCodeAt(i) ^ encblock[i])); - blockc = tempBlock.join(''); - tempBlock = []; - cyphertext.push(blockc); - pos++; - } - return cyphertext.join(''); -} - -function normal_cfb_decrypt(blockcipherencryptfn, block_size, key, ciphertext, iv) { - var blockp =""; - var pos = 0; - var plaintext = []; - var offset = 0; - if (iv == null) - for (var i = 0; i < block_size; i++) blockp += String.fromCharCode(0); - else - blockp = iv.substring(0,block_size); - while (ciphertext.length > (block_size*pos)) { - var decblock = blockcipherencryptfn(blockp, key); - blockp = ciphertext.substring((pos*(block_size))+offset,(pos*(block_size))+(block_size)+offset); - for (var i=0; i < blockp.length; i++) { - plaintext.push(String.fromCharCode(blockp.charCodeAt(i) ^ decblock[i])); - } - pos++; - } - - return plaintext.join(''); } /* A JavaScript implementation of the SHA family of hashes, as defined in FIPS * PUB 180-2 as well as the corresponding HMAC implementation as defined in @@ -11799,647 +5187,4372 @@ function RMDstring(message) } return retString; -}/** - * A fast MD5 JavaScript implementation - * Copyright (c) 2012 Joseph Myers - * http://www.myersdaily.org/joseph/javascript/md5-text.html - * - * Permission to use, copy, modify, and distribute this software - * and its documentation for any purposes and without - * fee is hereby granted provided that this copyright notice - * appears in all copies. - * - * Of course, this soft is provided "as is" without express or implied - * warranty of any kind. +}/* Modified by Recurity Labs GmbH + * + * Originally written by nklein software (nklein.com) */ -function MD5(entree) { - var hex = md5(entree); - var bin = util.hex2bin(hex); - return bin; -} - -function md5cycle(x, k) { -var a = x[0], b = x[1], c = x[2], d = x[3]; - -a = ff(a, b, c, d, k[0], 7, -680876936); -d = ff(d, a, b, c, k[1], 12, -389564586); -c = ff(c, d, a, b, k[2], 17, 606105819); -b = ff(b, c, d, a, k[3], 22, -1044525330); -a = ff(a, b, c, d, k[4], 7, -176418897); -d = ff(d, a, b, c, k[5], 12, 1200080426); -c = ff(c, d, a, b, k[6], 17, -1473231341); -b = ff(b, c, d, a, k[7], 22, -45705983); -a = ff(a, b, c, d, k[8], 7, 1770035416); -d = ff(d, a, b, c, k[9], 12, -1958414417); -c = ff(c, d, a, b, k[10], 17, -42063); -b = ff(b, c, d, a, k[11], 22, -1990404162); -a = ff(a, b, c, d, k[12], 7, 1804603682); -d = ff(d, a, b, c, k[13], 12, -40341101); -c = ff(c, d, a, b, k[14], 17, -1502002290); -b = ff(b, c, d, a, k[15], 22, 1236535329); - -a = gg(a, b, c, d, k[1], 5, -165796510); -d = gg(d, a, b, c, k[6], 9, -1069501632); -c = gg(c, d, a, b, k[11], 14, 643717713); -b = gg(b, c, d, a, k[0], 20, -373897302); -a = gg(a, b, c, d, k[5], 5, -701558691); -d = gg(d, a, b, c, k[10], 9, 38016083); -c = gg(c, d, a, b, k[15], 14, -660478335); -b = gg(b, c, d, a, k[4], 20, -405537848); -a = gg(a, b, c, d, k[9], 5, 568446438); -d = gg(d, a, b, c, k[14], 9, -1019803690); -c = gg(c, d, a, b, k[3], 14, -187363961); -b = gg(b, c, d, a, k[8], 20, 1163531501); -a = gg(a, b, c, d, k[13], 5, -1444681467); -d = gg(d, a, b, c, k[2], 9, -51403784); -c = gg(c, d, a, b, k[7], 14, 1735328473); -b = gg(b, c, d, a, k[12], 20, -1926607734); - -a = hh(a, b, c, d, k[5], 4, -378558); -d = hh(d, a, b, c, k[8], 11, -2022574463); -c = hh(c, d, a, b, k[11], 16, 1839030562); -b = hh(b, c, d, a, k[14], 23, -35309556); -a = hh(a, b, c, d, k[1], 4, -1530992060); -d = hh(d, a, b, c, k[4], 11, 1272893353); -c = hh(c, d, a, b, k[7], 16, -155497632); -b = hh(b, c, d, a, k[10], 23, -1094730640); -a = hh(a, b, c, d, k[13], 4, 681279174); -d = hh(d, a, b, c, k[0], 11, -358537222); -c = hh(c, d, a, b, k[3], 16, -722521979); -b = hh(b, c, d, a, k[6], 23, 76029189); -a = hh(a, b, c, d, k[9], 4, -640364487); -d = hh(d, a, b, c, k[12], 11, -421815835); -c = hh(c, d, a, b, k[15], 16, 530742520); -b = hh(b, c, d, a, k[2], 23, -995338651); - -a = ii(a, b, c, d, k[0], 6, -198630844); -d = ii(d, a, b, c, k[7], 10, 1126891415); -c = ii(c, d, a, b, k[14], 15, -1416354905); -b = ii(b, c, d, a, k[5], 21, -57434055); -a = ii(a, b, c, d, k[12], 6, 1700485571); -d = ii(d, a, b, c, k[3], 10, -1894986606); -c = ii(c, d, a, b, k[10], 15, -1051523); -b = ii(b, c, d, a, k[1], 21, -2054922799); -a = ii(a, b, c, d, k[8], 6, 1873313359); -d = ii(d, a, b, c, k[15], 10, -30611744); -c = ii(c, d, a, b, k[6], 15, -1560198380); -b = ii(b, c, d, a, k[13], 21, 1309151649); -a = ii(a, b, c, d, k[4], 6, -145523070); -d = ii(d, a, b, c, k[11], 10, -1120210379); -c = ii(c, d, a, b, k[2], 15, 718787259); -b = ii(b, c, d, a, k[9], 21, -343485551); - -x[0] = add32(a, x[0]); -x[1] = add32(b, x[1]); -x[2] = add32(c, x[2]); -x[3] = add32(d, x[3]); - -} - -function cmn(q, a, b, x, s, t) { -a = add32(add32(a, q), add32(x, t)); -return add32((a << s) | (a >>> (32 - s)), b); -} - -function ff(a, b, c, d, x, s, t) { -return cmn((b & c) | ((~b) & d), a, b, x, s, t); -} - -function gg(a, b, c, d, x, s, t) { -return cmn((b & d) | (c & (~d)), a, b, x, s, t); -} - -function hh(a, b, c, d, x, s, t) { -return cmn(b ^ c ^ d, a, b, x, s, t); -} - -function ii(a, b, c, d, x, s, t) { -return cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -function md51(s) { -txt = ''; -var n = s.length, -state = [1732584193, -271733879, -1732584194, 271733878], i; -for (i=64; i<=s.length; i+=64) { -md5cycle(state, md5blk(s.substring(i-64, i))); -} -s = s.substring(i-64); -var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; -for (i=0; i>2] |= s.charCodeAt(i) << ((i%4) << 3); -tail[i>>2] |= 0x80 << ((i%4) << 3); -if (i > 55) { -md5cycle(state, tail); -for (i=0; i<16; i++) tail[i] = 0; -} -tail[14] = n*8; -md5cycle(state, tail); -return state; -} - -/* there needs to be support for Unicode here, - * unless we pretend that we can redefine the MD-5 - * algorithm for multi-byte characters (perhaps - * by adding every four 16-bit characters and - * shortening the sum to 32 bits). Otherwise - * I suggest performing MD-5 as if every character - * was two bytes--e.g., 0040 0025 = @%--but then - * how will an ordinary MD-5 sum be matched? - * There is no way to standardize text to something - * like UTF-8 before transformation; speed cost is - * utterly prohibitive. The JavaScript standard - * itself needs to look at this: it should start - * providing access to strings as preformed UTF-8 - * 8-bit unsigned value arrays. +/* + * Javascript implementation based on Bruce Schneier's reference implementation. + * + * + * The constructor doesn't do much of anything. It's just here + * so we can start defining properties and methods and such. */ -function md5blk(s) { /* I figured global was faster. */ -var md5blks = [], i; /* Andy King said do it this way. */ -for (i=0; i<64; i+=4) { -md5blks[i>>2] = s.charCodeAt(i) -+ (s.charCodeAt(i+1) << 8) -+ (s.charCodeAt(i+2) << 16) -+ (s.charCodeAt(i+3) << 24); +function Blowfish() { +}; + +/* + * Declare the block size so that protocols know what size + * Initialization Vector (IV) they will need. + */ +Blowfish.prototype.BLOCKSIZE = 8; + +/* + * These are the default SBOXES. + */ +Blowfish.prototype.SBOXES = [ + [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, + 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, + 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, + 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, + 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, + 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, + 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, + 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, + 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, + 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, + 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, + 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, + 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, + 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, + 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, + 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, + 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, + 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, + 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, + 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, + 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, + 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ], [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, + 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, + 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, + 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, + 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, + 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, + 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, + 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, + 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, + 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, + 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, + 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, + 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, + 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, + 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, + 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, + 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, + 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ], [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, + 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, + 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, + 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, + 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, + 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, + 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, + 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, + 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, + 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, + 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, + 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, + 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, + 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, + 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, + 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, + 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, + 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, + 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, + 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, + 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, + 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ], [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, + 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, + 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, + 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, + 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, + 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, + 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, + 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, + 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, + 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, + 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, + 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, + 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, + 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, + 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, + 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, + 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, + 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, + 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, + 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, + 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, + 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ] +]; + +//* +//* This is the default PARRAY +//* +Blowfish.prototype.PARRAY = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, + 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b +]; + +//* +//* This is the number of rounds the cipher will go +//* +Blowfish.prototype.NN = 16; + +//* +//* This function is needed to get rid of problems +//* with the high-bit getting set. If we don't do +//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not +//* equal to ( bb & 0x00FFFFFFFF ) even when they +//* agree bit-for-bit for the first 32 bits. +//* +Blowfish.prototype._clean = function( xx ) { + if ( xx < 0 ) { + var yy = xx & 0x7FFFFFFF; + xx = yy + 0x80000000; + } + return xx; +}; + +//* +//* This is the mixing function that uses the sboxes +//* +Blowfish.prototype._F = function ( xx ) { + var aa; + var bb; + var cc; + var dd; + var yy; + + dd = xx & 0x00FF; + xx >>>= 8; + cc = xx & 0x00FF; + xx >>>= 8; + bb = xx & 0x00FF; + xx >>>= 8; + aa = xx & 0x00FF; + + yy = this.sboxes[ 0 ][ aa ] + this.sboxes[ 1 ][ bb ]; + yy = yy ^ this.sboxes[ 2 ][ cc ]; + yy = yy + this.sboxes[ 3 ][ dd ]; + + return yy; +}; + +//* +//* This method takes an array with two values, left and right +//* and does NN rounds of Blowfish on them. +//* +Blowfish.prototype._encrypt_block = function ( vals ) { + var dataL = vals[ 0 ]; + var dataR = vals[ 1 ]; + + var ii; + + for ( ii=0; ii < this.NN; ++ii ) { + dataL = dataL ^ this.parray[ ii ]; + dataR = this._F( dataL ) ^ dataR; + + var tmp = dataL; + dataL = dataR; + dataR = tmp; + } + + dataL = dataL ^ this.parray[ this.NN + 0 ]; + dataR = dataR ^ this.parray[ this.NN + 1 ]; + + vals[ 0 ] = this._clean( dataR ); + vals[ 1 ] = this._clean( dataL ); +}; + +//* +//* This method takes a vector of numbers and turns them +//* into long words so that they can be processed by the +//* real algorithm. +//* +//* Maybe I should make the real algorithm above take a vector +//* instead. That will involve more looping, but it won't require +//* the F() method to deconstruct the vector. +//* +Blowfish.prototype.encrypt_block = function ( vector ) { + var ii; + var vals = [ 0, 0 ]; + var off = this.BLOCKSIZE/2; + for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { + vals[0] = ( vals[0] << 8 ) | ( vector[ ii + 0 ] & 0x00FF ); + vals[1] = ( vals[1] << 8 ) | ( vector[ ii + off ] & 0x00FF ); + } + + this._encrypt_block( vals ); + + var ret = [ ]; + for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { + ret[ ii + 0 ] = ( vals[ 0 ] >>> (24 - 8*(ii)) & 0x00FF ); + ret[ ii + off ] = ( vals[ 1 ] >>> (24 - 8*(ii)) & 0x00FF ); + // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); + // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); + } + + return ret; +}; + +//* +//* This method takes an array with two values, left and right +//* and undoes NN rounds of Blowfish on them. +//* +Blowfish.prototype._decrypt_block = function ( vals ) { + var dataL = vals[ 0 ]; + var dataR = vals[ 1 ]; + + var ii; + + for ( ii=this.NN+1; ii > 1; --ii ) { + dataL = dataL ^ this.parray[ ii ]; + dataR = this._F( dataL ) ^ dataR; + + var tmp = dataL; + dataL = dataR; + dataR = tmp; + } + + dataL = dataL ^ this.parray[ 1 ]; + dataR = dataR ^ this.parray[ 0 ]; + + vals[ 0 ] = this._clean( dataR ); + vals[ 1 ] = this._clean( dataL ); +}; + +//* +//* This method takes a key array and initializes the +//* sboxes and parray for this encryption. +//* +Blowfish.prototype.init = function ( key ) { + var ii; + var jj = 0; + + this.parray = []; + for ( ii=0; ii < this.NN + 2; ++ii ) { + var data = 0x00000000; + var kk; + for ( kk=0; kk < 4; ++kk ) { + data = ( data << 8 ) | ( key[ jj ] & 0x00FF ); + if ( ++jj >= key.length ) { + jj = 0; + } + } + this.parray[ ii ] = this.PARRAY[ ii ] ^ data; + } + + this.sboxes = []; + for ( ii=0; ii < 4; ++ii ) { + this.sboxes[ ii ] = []; + for ( jj=0; jj < 256; ++jj ) { + this.sboxes[ ii ][ jj ] = this.SBOXES[ ii ][ jj ]; + } + } + + var vals = [ 0x00000000, 0x00000000 ]; + + for ( ii=0; ii < this.NN+2; ii += 2 ) { + this._encrypt_block( vals ); + this.parray[ ii + 0 ] = vals[ 0 ]; + this.parray[ ii + 1 ] = vals[ 1 ]; + } + + for ( ii=0; ii < 4; ++ii ) { + for ( jj=0; jj < 256; jj += 2 ) { + this._encrypt_block( vals ); + this.sboxes[ ii ][ jj + 0 ] = vals[ 0 ]; + this.sboxes[ ii ][ jj + 1 ] = vals[ 1 ]; + } + } +}; + +// added by Recurity Labs +function BFencrypt(block,key) { + var bf = new Blowfish(); + bf.init(util.str2bin(key)); + return bf.encrypt_block(block); } -return md5blks; +//Paul Tero, July 2001 +//http://www.tero.co.uk/des/ +// +//Optimised for performance with large blocks by Michael Hayworth, November 2001 +//http://www.netdealing.com +// +// Modified by Recurity Labs GmbH + +//THIS SOFTWARE IS PROVIDED "AS IS" AND +//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +//SUCH DAMAGE. + +//des +//this takes the key, the message, and whether to encrypt or decrypt + +// added by Recurity Labs +function desede(block,key) { + var key1 = key.substring(0,8); + var key2 = key.substring(8,16); + var key3 = key.substring(16,24); + return util.str2bin(des(des_createKeys(key3),des(des_createKeys(key2),des(des_createKeys(key1),util.bin2str(block), true, 0,null,null), false, 0,null,null), true, 0,null,null)); } -var hex_chr = '0123456789abcdef'.split(''); -function rhex(n) +function des (keys, message, encrypt, mode, iv, padding) { + //declaring this locally speeds things up a bit + var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004); + var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000); + var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200); + var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080); + var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100); + var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010); + var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002); + var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000); + + //create the 16 or 48 subkeys we will need + var m=0, i, j, temp, temp2, right1, right2, left, right, looping; + var cbcleft, cbcleft2, cbcright, cbcright2 + var endloop, loopinc; + var len = message.length; + var chunk = 0; + //set up the loops for single and triple des + var iterations = keys.length == 32 ? 3 : 9; //single or triple des + if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);} + else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);} + + //pad the message depending on the padding parameter + if (padding == 2) message += " "; //pad the message with spaces + else if (padding == 1) {temp = 8-(len%8); message += String.fromCharCode (temp,temp,temp,temp,temp,temp,temp,temp); if (temp==8) len+=8;} //PKCS7 padding + else if (!padding) message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes + + //store the result here + result = ""; + tempresult = ""; + + if (mode == 1) { //CBC mode + cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); + cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); + m=0; + } + + //loop through each 64 bit chunk of the message + while (m < len) { + left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); + right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); + + //for Cipher Block Chaining mode, xor the message with the previous result + if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}} + + //first each 64 but chunk of the message must be permuted according to IP + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); + temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); + temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + + left = ((left << 1) | (left >>> 31)); + right = ((right << 1) | (right >>> 31)); + + //do this either 1 or 3 times for each chunk of the message + for (j=0; j>> 4) | (right << 28)) ^ keys[i+1]; + //the result is attained by passing these bytes through the S selection functions + temp = left; + left = right; + right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] + | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] + | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] + | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); + } + temp = left; left = right; right = temp; //unreverse left and right + } //for either 1 or 3 iterations + + //move then each one bit to the right + left = ((left >>> 1) | (left << 31)); + right = ((right >>> 1) | (right << 31)); + + //now perform IP-1, which is IP in the opposite direction + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); + temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); + temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); + + //for Cipher Block Chaining mode, xor the message with the previous result + if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}} + tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff)); + + chunk += 8; + if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;} + } //for every 8 characters, or 64 bits in the message + + //return the result as an array + result += tempresult; + result = result.replace(/\0*$/g, ""); + return result; +} //end of des + + + +//des_createKeys +//this takes as input a 64 bit key (even though only 56 bits are used) +//as an array of 2 integers, and returns 16 48 bit keys +function des_createKeys (key) { + //declaring this locally speeds things up a bit + pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204); + pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101); + pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808); + pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000); + pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010); + pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420); + pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002); + pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800); + pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002); + pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408); + pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020); + pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200); + pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010); + pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105); + + //how many iterations (1 for des, 3 for triple des) + var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys + //stores the return keys + var keys = new Array (32 * iterations); + //now define the left shifts which need to be done + var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); + //other variables + var lefttemp, righttemp, m=0, n=0, temp; + + for (var j=0; j>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); + temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); + temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2); + temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); + temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + + //the right side needs to be shifted and to get the last four bits of the left side + temp = (left << 8) | ((right >>> 20) & 0x000000f0); + //left needs to be put upside down + left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0); + right = temp; + + //now go through and perform these shifts on the left and right keys + for (i=0; i < shifts.length; i++) { + //shift the keys either one or two bits to the left + if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);} + else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);} + left &= -0xf; right &= -0xf; + + //now apply PC-2, in such a way that E is easier when encrypting or decrypting + //this conversion will look like PC-2 except only the last 6 bits of each byte are used + //rather than 48 consecutive bits and the order of lines will be according to + //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 + lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] + | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] + | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] + | pc2bytes6[(left >>> 4) & 0xf]; + righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] + | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] + | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] + | pc2bytes13[(right >>> 4) & 0xf]; + temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; + keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16); + } + } //for each iterations + //return the keys we've created + return keys; +} //end of des_createKeys + + + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Copyright 2010 pjacobs@xeekr.com . All rights reserved. + +// Modified by Recurity Labs GmbH + +// fixed/modified by Herbert Hanewinkel, www.haneWIN.de +// check www.haneWIN.de for the latest version + +// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144. +// CAST-128 is a common OpenPGP cipher. + + +// CAST5 constructor + +function cast5_encrypt(block, key) { + var cast5 = new openpgp_symenc_cast5(); + cast5.setKey(util.str2bin(key)); + return cast5.encrypt(block); +} + +function openpgp_symenc_cast5() { + this.BlockSize= 8; + this.KeySize = 16; + + this.setKey = function (key) { + this.masking = new Array(16); + this.rotate = new Array(16); + + this.reset(); + + if (key.length == this.KeySize) + { + this.keySchedule(key); + } + else + { + util.print_error('cast5.js: CAST-128: keys must be 16 bytes'); + return false; + } + return true; + }; + + this.reset = function() { + for (var i = 0; i < 16; i++) + { + this.masking[i] = 0; + this.rotate[i] = 0; + } + }; + + this.getBlockSize = function() { + return BlockSize; + }; + + this.encrypt = function(src) { + var dst = new Array(src.length); + + for(i = 0; i < src.length; i+=8) + { + var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; + var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; + var t; + + t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; + t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; + t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; + t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; + + t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; + t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; + t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; + t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; + + t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; + t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; + t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; + t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; + + t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; + t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; + t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; + t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; + + dst[i] = (r >>> 24)&255; + dst[i+1] = (r >>> 16)&255; + dst[i+2] = (r >>> 8)&255; + dst[i+3] = r&255; + dst[i+4] = (l >>> 24)&255; + dst[i+5] = (l >>> 16)&255; + dst[i+6] = (l >>> 8)&255; + dst[i+7] = l&255; + } + + return dst; + }; + + this.decrypt = function(src) { + var dst = new Array(src.length); + + for(i = 0; i < src.length; i+=8) + { + var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; + var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; + var t; + + t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; + t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; + t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; + t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; + + t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; + t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; + t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; + t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; + + t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; + t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; + t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; + t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; + + t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; + t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; + t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; + t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; + + dst[i] = (r >>> 24)&255; + dst[i+1] = (r >>> 16)&255; + dst[i+2] = (r >>> 8)&255; + dst[i+3] = r&255; + dst[i+4] = (l >>> 24)&255; + dst[i+5] = (l >> 16)&255; + dst[i+6] = (l >> 8)&255; + dst[i+7] = l&255; + } + + return dst; + }; + var scheduleA = new Array(4); + + scheduleA[0] = new Array(4); + scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8); + scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); + scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); + scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); + + scheduleA[1] = new Array(4); + scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); + scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); + scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); + scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); + + scheduleA[2] = new Array(4); + scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8); + scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); + scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); + scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); + + + scheduleA[3] = new Array(4); + scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); + scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); + scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); + scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); + + var scheduleB = new Array(4); + + scheduleB[0] = new Array(4); + scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2); + scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6); + scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9); + scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc); + + scheduleB[1] = new Array(4); + scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8); + scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd); + scheduleB[1][2] = new Array(7, 6, 8, 9, 3); + scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7); + + + scheduleB[2] = new Array(4); + scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9); + scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc); + scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2); + scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6); + + + scheduleB[3] = new Array(4); + scheduleB[3][0] = new Array(8, 9, 7, 6, 3); + scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7); + scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8); + scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd); + + // changed 'in' to 'inn' (in javascript 'in' is a reserved word) + this.keySchedule = function(inn) + { + var t = new Array(8); + var k = new Array(32); + + for (var i = 0; i < 4; i++) + { + var j = i * 4; + t[i] = inn[j]<<24 | inn[j+1]<<16 | inn[j+2]<<8 | inn[j+3]; + } + + var x = [6, 7, 4, 5]; + var ki = 0; + + for (var half = 0; half < 2; half++) + { + for (var round = 0; round < 4; round++) + { + for (var j = 0; j < 4; j++) + { + var a = scheduleA[round][j]; + var w = t[a[1]]; + + w ^= sBox[4][(t[a[2]>>>2]>>>(24-8*(a[2]&3)))&0xff]; + w ^= sBox[5][(t[a[3]>>>2]>>>(24-8*(a[3]&3)))&0xff]; + w ^= sBox[6][(t[a[4]>>>2]>>>(24-8*(a[4]&3)))&0xff]; + w ^= sBox[7][(t[a[5]>>>2]>>>(24-8*(a[5]&3)))&0xff]; + w ^= sBox[x[j]][(t[a[6]>>>2]>>>(24-8*(a[6]&3)))&0xff]; + t[a[0]] = w; + } + + for (var j = 0; j < 4; j++) + { + var b = scheduleB[round][j]; + var w = sBox[4][(t[b[0]>>>2]>>>(24-8*(b[0]&3)))&0xff]; + + w ^= sBox[5][(t[b[1]>>>2]>>>(24-8*(b[1]&3)))&0xff]; + w ^= sBox[6][(t[b[2]>>>2]>>>(24-8*(b[2]&3)))&0xff]; + w ^= sBox[7][(t[b[3]>>>2]>>>(24-8*(b[3]&3)))&0xff]; + w ^= sBox[4+j][(t[b[4]>>>2]>>>(24-8*(b[4]&3)))&0xff]; + k[ki] = w; + ki++; + } + } + } + + for (var i = 0; i < 16; i++) + { + this.masking[i] = k[i]; + this.rotate[i] = k[16+i] & 0x1f; + } + }; + + // These are the three 'f' functions. See RFC 2144, section 2.2. + + function f1(d, m, r) + { + var t = m + d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I>>>24] ^ sBox[1][(I>>>16)&255]) - sBox[2][(I>>>8)&255]) + sBox[3][I&255]; + } + + function f2(d, m, r) + { + var t = m ^ d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I>>>24] - sBox[1][(I>>>16)&255]) + sBox[2][(I>>>8)&255]) ^ sBox[3][I&255]; + } + + function f3(d, m, r) + { + var t = m - d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I>>>24] + sBox[1][(I>>>16)&255]) ^ sBox[2][(I>>>8)&255]) - sBox[3][I&255]; + } + + var sBox = new Array(8); + sBox[0] = new Array( + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf); + + sBox[1] = new Array( + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1); + + sBox[2] = new Array( + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783); + + sBox[3] = new Array( + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2); + + sBox[4] = new Array( + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4); + + sBox[5] = new Array( + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f); + + sBox[6] = new Array( + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3); + + sBox[7] = new Array( + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e); + +}; + + +/* Rijndael (AES) Encryption + * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de + * version 1.1, check www.haneWIN.de for the latest version + + * This software is provided as-is, without express or implied warranty. + * Permission to use, copy, modify, distribute or sell this software, with or + * without fee, for any purpose and by any individual or organization, is hereby + * granted, provided that the above copyright notice and this paragraph appear + * in all copies. Distribution as a part of an application or binary must + * include the above copyright notice in the documentation and/or other + * materials provided with the application or distribution. + */ + +// The round constants used in subkey expansion +var Rcon = [ +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 ]; + +// Precomputed lookup table for the SBox +var S = [ + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, +118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, +114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, +216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, +235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, +179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, +190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, +249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, +188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, +23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, +144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, + 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, +141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, + 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, +181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, +248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, +140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, + 22 ]; + +var T1 = [ +0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, +0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, +0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, +0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, +0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, +0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, +0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, +0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, +0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, +0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, +0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, +0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, +0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, +0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, +0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, +0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, +0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, +0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, +0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, +0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, +0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, +0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, +0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, +0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, +0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, +0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, +0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, +0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, +0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, +0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, +0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, +0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, +0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, +0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, +0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, +0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, +0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, +0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, +0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, +0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, +0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, +0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, +0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, +0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, +0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, +0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, +0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, +0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, +0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, +0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, +0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, +0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, +0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, +0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, +0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, +0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, +0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, +0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, +0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, +0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, +0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, +0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, +0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, +0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c ]; + +var T2 = [ +0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, +0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, +0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, +0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, +0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, +0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, +0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, +0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, +0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, +0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, +0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, +0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, +0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, +0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, +0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, +0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, +0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, +0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, +0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, +0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, +0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, +0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, +0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, +0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, +0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, +0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, +0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, +0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, +0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, +0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, +0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, +0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, +0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, +0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, +0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, +0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, +0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, +0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, +0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, +0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, +0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, +0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, +0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, +0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, +0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, +0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, +0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, +0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, +0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, +0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, +0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, +0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, +0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, +0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, +0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, +0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, +0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, +0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, +0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, +0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, +0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, +0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, +0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, +0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a ]; + +var T3 = [ +0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, +0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, +0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, +0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, +0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, +0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, +0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, +0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, +0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, +0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, +0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, +0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, +0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, +0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, +0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, +0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, +0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, +0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, +0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, +0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, +0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, +0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, +0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, +0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, +0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, +0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, +0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, +0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, +0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, +0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, +0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, +0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, +0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, +0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, +0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, +0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, +0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, +0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, +0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, +0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, +0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, +0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, +0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, +0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, +0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, +0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, +0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, +0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, +0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, +0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, +0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, +0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, +0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, +0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, +0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, +0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, +0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, +0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, +0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, +0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, +0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, +0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, +0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, +0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 ]; + +var T4 = [ +0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, +0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, +0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, +0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, +0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, +0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, +0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, +0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, +0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, +0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, +0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, +0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, +0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, +0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, +0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, +0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, +0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, +0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, +0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, +0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, +0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, +0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, +0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, +0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, +0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, +0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, +0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, +0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, +0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, +0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, +0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, +0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, +0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, +0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, +0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, +0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, +0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, +0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, +0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, +0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, +0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, +0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, +0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, +0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, +0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, +0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, +0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, +0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, +0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, +0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, +0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, +0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, +0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, +0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, +0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, +0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, +0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, +0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, +0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, +0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, +0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, +0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, +0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, +0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 ]; + +function B0(x) { return (x&255); } +function B1(x) { return ((x>>8)&255); } +function B2(x) { return ((x>>16)&255); } +function B3(x) { return ((x>>24)&255); } + +function F1(x0, x1, x2, x3) { -var s='', j=0; -for(; j<4; j++) -s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] -+ hex_chr[(n >> (j * 8)) & 0x0F]; -return s; + return B1(T1[x0&255]) | (B1(T1[(x1>>8)&255])<<8) + | (B1(T1[(x2>>16)&255])<<16) | (B1(T1[x3>>>24])<<24); } -function hex(x) { -for (var i=0; i=0; j--) tk[j] = k[j]; + + r=0; + t=0; + for(j=0; (j> 16) + (y >> 16) + (lsw >> 16); -return (msw << 16) | (lsw & 0xFFFF); +function AESencrypt(block, ctx) +{ + var r; + var t0,t1,t2,t3; + + var b = packBytes(block); + var rounds = ctx.rounds; + var b0 = b[0]; + var b1 = b[1]; + var b2 = b[2]; + var b3 = b[3]; + + for(r=0; r>8)&255] ^ T3[(t2>>16)&255] ^ T4[t3>>>24]; + b1 = T1[t1&255] ^ T2[(t2>>8)&255] ^ T3[(t3>>16)&255] ^ T4[t0>>>24]; + b2 = T1[t2&255] ^ T2[(t3>>8)&255] ^ T3[(t0>>16)&255] ^ T4[t1>>>24]; + b3 = T1[t3&255] ^ T2[(t0>>8)&255] ^ T3[(t1>>16)&255] ^ T4[t2>>>24]; + } + + // last round is special + r = rounds-1; + + t0 = b0 ^ ctx.rk[r][0]; + t1 = b1 ^ ctx.rk[r][1]; + t2 = b2 ^ ctx.rk[r][2]; + t3 = b3 ^ ctx.rk[r][3]; + + b[0] = F1(t0, t1, t2, t3) ^ ctx.rk[rounds][0]; + b[1] = F1(t1, t2, t3, t0) ^ ctx.rk[rounds][1]; + b[2] = F1(t2, t3, t0, t1) ^ ctx.rk[rounds][2]; + b[3] = F1(t3, t0, t1, t2) ^ ctx.rk[rounds][3]; + + return unpackBytes(b); } +/* Modified by Recurity Labs GmbH + * + * Cipher.js + * A block-cipher algorithm implementation on JavaScript + * See Cipher.readme.txt for further information. + * + * Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ] + * This script file is distributed under the LGPL + * + * ACKNOWLEDGMENT + * + * The main subroutines are written by Michiel van Everdingen. + * + * Michiel van Everdingen + * http://home.versatel.nl/MAvanEverdingen/index.html + * + * All rights for these routines are reserved to Michiel van Everdingen. + * + */ + +// added by Recurity Labs +function TFencrypt(block, key) { + var block_copy = [].concat(block); + var tf = createTwofish(); + tf.open(util.str2bin(key),0); + var result = tf.encrypt(block_copy, 0); + tf.close(); + return result; } -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -function openpgp_keyring() { - - /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). - * @return [null] undefined - */ - function init() { - var sprivatekeys = JSON.parse(window.localStorage.getItem("privatekeys")); - var spublickeys = JSON.parse(window.localStorage.getItem("publickeys")); - if (sprivatekeys == null || sprivatekeys.length == 0) { - sprivatekeys = new Array(); - } +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Math +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (spublickeys == null || spublickeys.length == 0) { - spublickeys = new Array(); - } - this.publicKeys = new Array(); - this.privateKeys = new Array(); - var k = 0; - for (var i =0; i < sprivatekeys.length; i++) { - var r = openpgp.read_privateKey(sprivatekeys[i]); - this.privateKeys[k] = { armored: sprivatekeys[i], obj: r[0], keyId: r[0].getKeyId()}; - k++; - } - k = 0; - for (var i =0; i < spublickeys.length; i++) { - var r = openpgp.read_publicKey(spublickeys[i]); - if (r[0] != null) { - this.publicKeys[k] = { armored: spublickeys[i], obj: r[0], keyId: r[0].getKeyId()}; - k++; - } - } - } - this.init = init; +var MAXINT = 0xFFFFFFFF; - /** - * Checks if at least one private key is in the keyring - * @return {boolean} True if there are private keys, else false. - */ - function hasPrivateKey() { - return this.privateKeys.length > 0; - } - this.hasPrivateKey = hasPrivateKey; +function rotb(b,n){ return ( b<>>( 8-n) ) & 0xFF; } +function rotw(w,n){ return ( w<>>(32-n) ) & MAXINT; } +function getW(a,i){ return a[i]|a[i+1]<<8|a[i+2]<<16|a[i+3]<<24; } +function setW(a,i,w){ a.splice(i,4,w&0xFF,(w>>>8)&0xFF,(w>>>16)&0xFF,(w>>>24)&0xFF); } +function setWInv(a,i,w){ a.splice(i,4,(w>>>24)&0xFF,(w>>>16)&0xFF,(w>>>8)&0xFF,w&0xFF); } +function getB(x,n){ return (x>>>(n*8))&0xFF; } - /** - * Saves the current state of the keyring to HTML5 local storage. - * The privateKeys array and publicKeys array gets Stringified using JSON - * @return [null] undefined - */ - function store() { - var priv = new Array(); - for (var i = 0; i < this.privateKeys.length; i++) { - priv[i] = this.privateKeys[i].armored; - } - var pub = new Array(); - for (var i = 0; i < this.publicKeys.length; i++) { - pub[i] = this.publicKeys[i].armored; - } - window.localStorage.setItem("privatekeys",JSON.stringify(priv)); - window.localStorage.setItem("publickeys",JSON.stringify(pub)); - } - this.store = store; - /** - * searches all public keys in the keyring matching the address or address part of the user ids - * @param email_address - * @return {array[openpgp_msg_publickey]} the public keys associated with provided email address. - */ - function getPublicKeyForAddress(email_address) { - var results = new Array(); - var spl = email_address.split("<"); - var email = ""; - if (spl.length > 1) { - email = spl[1].split(">")[0]; - } else { - email = email_address.trim(); - } - email = email.toLowerCase(); - if(!util.emailRegEx.test(email)){ - return results; - } - for (var i =0; i < this.publicKeys.length; i++) { - for (var j = 0; j < this.publicKeys[i].obj.userIds.length; j++) { - if (this.publicKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0) - results[results.length] = this.publicKeys[i]; - } - } - return results; - } - this.getPublicKeyForAddress = getPublicKeyForAddress; - - /** - * Searches the keyring for a private key containing the specified email address - * @param {String} email_address email address to search for - * @return {Array[openpgp_msg_privatekey} private keys found - */ - function getPrivateKeyForAddress(email_address) { - var results = new Array(); - var spl = email_address.split("<"); - var email = ""; - if (spl.length > 1) { - email = spl[1].split(">")[0]; - } else { - email = email_address.trim(); - } - email = email.toLowerCase(); - if(!util.emailRegEx.test(email)){ - return results; - } - for (var i =0; i < this.privateKeys.length; i++) { - for (var j = 0; j < this.privateKeys[i].obj.userIds.length; j++) { - if (this.privateKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0) - results[results.length] = this.privateKeys[i]; - } - } - return results; - } - - this.getPrivateKeyForAddress = getPrivateKeyForAddress; - /** - * Searches the keyring for public keys having the specified key id - * @param keyId provided as string of hex number (lowercase) - * @return {Array[openpgp_msg_privatekey]} public keys found - */ - function getPublicKeysForKeyId(keyId) { - var result = new Array(); - for (var i=0; i < this.publicKeys.length; i++) - if (keyId == this.publicKeys[i].obj.getKeyId()) - result[result.length] = this.publicKeys[i]; - return result; - } - this.getPublicKeysForKeyId = getPublicKeysForKeyId; - - /** - * Searches the keyring for private keys having the specified key id - * @param keyId [String] 8 bytes as string containing the key id to look for - * @return Array[openpgp_msg_privatekey] private keys found - */ - function getPrivateKeyForKeyId(keyId) { - var result = new Array(); - for (var i=0; i < this.privateKeys.length; i++) { - if (keyId == this.privateKeys[i].obj.getKeyId()) { - result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.privateKeyPacket}; - } - if (this.privateKeys[i].obj.subKeys != null) { - var subkeyids = this.privateKeys[i].obj.getSubKeyIds(); - for (var j=0; j < subkeyids.length; j++) - if (keyId == util.hexstrdump(subkeyids[j])) { - result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.subKeys[j]}; - } - } - } - return result; - } - this.getPrivateKeyForKeyId = getPrivateKeyForKeyId; - - /** - * Imports a public key from an exported ascii armored message - * @param armored_text [String] PUBLIC KEY BLOCK message to read the public key from - * @return [null] nothing - */ - function importPublicKey (armored_text) { - var result = openpgp.read_publicKey(armored_text); - for (var i = 0; i < result.length; i++) { - this.publicKeys[this.publicKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()}; - } - return true; - } - - /** - * Imports a private key from an exported ascii armored message - * @param armored_text [String] PRIVATE KEY BLOCK message to read the private key from - * @return [null] nothing - */ - function importPrivateKey (armored_text, password) { - var result = openpgp.read_privateKey(armored_text); - if(!result[0].decryptSecretMPIs(password)) - return false; - for (var i = 0; i < result.length; i++) { - this.privateKeys[this.privateKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()}; - } - return true; - } - - this.importPublicKey = importPublicKey; - this.importPrivateKey = importPrivateKey; - - /** - * returns the openpgp_msg_privatekey representation of the public key at public key ring index - * @param index [Integer] the index of the public key within the publicKeys array - * @return [openpgp_msg_privatekey] the public key object - */ - function exportPublicKey(index) { - return this.publicKey[index]; - } - this.exportPublicKey = exportPublicKey; - - - /** - * Removes a public key from the public key keyring at the specified index - * @param index [Integer] the index of the public key within the publicKeys array - * @return [openpgp_msg_privatekey] The public key object which has been removed - */ - function removePublicKey(index) { - var removed = this.publicKeys.splice(index,1); - this.store(); - return removed; - } - this.removePublicKey = removePublicKey; - - /** - * returns the openpgp_msg_privatekey representation of the private key at private key ring index - * @param index [Integer] the index of the private key within the privateKeys array - * @return [openpgp_msg_privatekey] the private key object - */ - function exportPrivateKey(index) { - return this.privateKeys[index]; - } - this.exportPrivateKey = exportPrivateKey; - - /** - * Removes a private key from the private key keyring at the specified index - * @param index [Integer] the index of the private key within the privateKeys array - * @return [openpgp_msg_privatekey] The private key object which has been removed - */ - function removePrivateKey(index) { - var removed = this.privateKeys.splice(index,1); - this.store(); - return removed; - } - this.removePrivateKey = removePrivateKey; +function getNrBits(i){ var n=0; while (i>0){ n++; i>>>=1; } return n; } +function getMask(n){ return (1< pos) { - var result = openpgp_packet.read_packet(input, pos, input.length - pos); - if (result == null) { - util.print_error("openpgp.msg.messge decrypt:\n"+'[pub/priv_key]parsing ends here @:' + pos + " l:" + len); - break; - } else { - switch (result.tagType) { - case 2: // public key revocation signature - if (result.signatureType == 32) - this.revocationSignatures[this.revocationSignatures.length] = result; - else if (result.signatureType > 15 && result.signatureType < 20) { - if (this.certificationsignatures == null) - this.certificationSignatures = new Array(); - this.certificationSignatures[this.certificationSignatures.length] = result; - } else - util.print_error("openpgp.msg.messge decrypt:\n"+"unknown signature type directly on key "+result.signatureType+" @"+pos); - pos += result.packetLength + result.headerLength; - break; - case 7: // PrivateSubkey Packet - this.subKeys[this.subKeys.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.privateKeyPacket,input, pos, input.length - pos); - break; - case 17: // User Attribute Packet - this.userAttributes[this.userAttributes.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.privateKeyPacket,input, pos, input.length - pos); - break; - case 13: // User ID Packet - this.userIds[this.userIds.length] = result; - pos += result.packetLength + result.headerLength; - pos += result.read_nodes(this.privateKeyPacket, input, pos, input.length - pos); - break; - default: - this.position = position - this.privateKeyPacket.packetLength - this.privateKeyPacket.headerLength; - this.len = pos - position; - return this.len; + algorithmName = "twofish"; + + var tfsKey = []; + var tfsM = [ [], [], [], [] ]; + + function tfsInit(key) { + keyBytes = key; + var i, a, b, c, d, meKey = [], moKey = [], inKey = []; + var kLen; + var sKey = []; + var f01, f5b, fef; + + var q0 = [ [ 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 ], + [ 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 ] ]; + var q1 = [ [ 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 ], + [ 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 ] ]; + var q2 = [ [ 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 ], + [ 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 ] ]; + var q3 = [ [ 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 ], + [ 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 ] ]; + var ror4 = [ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 ]; + var ashx = [ 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 ]; + var q = [ [], [] ]; + var m = [ [], [], [], [] ]; + + function ffm5b(x) { + return x ^ (x >> 2) ^ [ 0, 90, 180, 238 ][x & 3]; + } + function ffmEf(x) { + return x ^ (x >> 1) ^ (x >> 2) ^ [ 0, 238, 180, 90 ][x & 3]; + } + + function mdsRem(p, q) { + var i, t, u; + for (i = 0; i < 8; i++) { + t = q >>> 24; + q = ((q << 8) & MAXINT) | p >>> 24; + p = (p << 8) & MAXINT; + u = t << 1; + if (t & 128) { + u ^= 333; } + q ^= t ^ (u << 16); + u ^= t >>> 1; + if (t & 1) { + u ^= 166; + } + q ^= u << 24 | u << 8; + } + return q; + } + + function qp(n, x) { + var a, b, c, d; + a = x >> 4; + b = x & 15; + c = q0[n][a ^ b]; + d = q1[n][ror4[b] ^ ashx[a]]; + return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; + } + + function hFun(x, key) { + var a = getB(x, 0), b = getB(x, 1), c = getB(x, 2), d = getB(x, 3); + switch (kLen) { + case 4: + a = q[1][a] ^ getB(key[3], 0); + b = q[0][b] ^ getB(key[3], 1); + c = q[0][c] ^ getB(key[3], 2); + d = q[1][d] ^ getB(key[3], 3); + case 3: + a = q[1][a] ^ getB(key[2], 0); + b = q[1][b] ^ getB(key[2], 1); + c = q[0][c] ^ getB(key[2], 2); + d = q[0][d] ^ getB(key[2], 3); + case 2: + a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); + b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); + c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2); + d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3); + } + return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d]; + } + + keyBytes = keyBytes.slice(0, 32); + i = keyBytes.length; + while (i != 16 && i != 24 && i != 32) + keyBytes[i++] = 0; + + for (i = 0; i < keyBytes.length; i += 4) { + inKey[i >> 2] = getW(keyBytes, i); + } + for (i = 0; i < 256; i++) { + q[0][i] = qp(0, i); + q[1][i] = qp(1, i); + } + for (i = 0; i < 256; i++) { + f01 = q[1][i]; + f5b = ffm5b(f01); + fef = ffmEf(f01); + m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); + m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); + f01 = q[0][i]; + f5b = ffm5b(f01); + fef = ffmEf(f01); + m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); + m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); + } + + kLen = inKey.length / 2; + for (i = 0; i < kLen; i++) { + a = inKey[i + i]; + meKey[i] = a; + b = inKey[i + i + 1]; + moKey[i] = b; + sKey[kLen - i - 1] = mdsRem(a, b); + } + for (i = 0; i < 40; i += 2) { + a = 0x1010101 * i; + b = a + 0x1010101; + a = hFun(a, meKey); + b = rotw(hFun(b, moKey), 8); + tfsKey[i] = (a + b) & MAXINT; + tfsKey[i + 1] = rotw(a + 2 * b, 9); + } + for (i = 0; i < 256; i++) { + a = b = c = d = i; + switch (kLen) { + case 4: + a = q[1][a] ^ getB(sKey[3], 0); + b = q[0][b] ^ getB(sKey[3], 1); + c = q[0][c] ^ getB(sKey[3], 2); + d = q[1][d] ^ getB(sKey[3], 3); + case 3: + a = q[1][a] ^ getB(sKey[2], 0); + b = q[1][b] ^ getB(sKey[2], 1); + c = q[0][c] ^ getB(sKey[2], 2); + d = q[0][d] ^ getB(sKey[2], 3); + case 2: + tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] + ^ getB(sKey[0], 0)]; + tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] + ^ getB(sKey[0], 1)]; + tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] + ^ getB(sKey[0], 2)]; + tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] + ^ getB(sKey[0], 3)]; } } - this.position = position - this.privateKeyPacket.packetLength - this.privateKeyPacket.headerLength; - this.len = pos - position; - - return this.len; } - - function getKeyId() { - return this.privateKeyPacket.publicKey.getKeyId(); + + function tfsG0(x) { + return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] + ^ tfsM[3][getB(x, 3)]; } - - - function getSubKeyIds() { - if (this.privateKeyPacket.publicKey.version == 4) // V3 keys MUST NOT have subkeys. - var result = new Array(); - for (var i = 0; i < this.subKeys.length; i++) { - result[i] = str_sha1(this.subKeys[i].publicKey.header+this.subKeys[i].publicKey.data).substring(12,20); + function tfsG1(x) { + return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] + ^ tfsM[3][getB(x, 2)]; + } + + function tfsFrnd(r, blk) { + var a = tfsG0(blk[0]); + var b = tfsG1(blk[1]); + blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); + blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; + a = tfsG0(blk[2]); + b = tfsG1(blk[3]); + blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); + blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; + } + + function tfsIrnd(i, blk) { + var a = tfsG0(blk[0]); + var b = tfsG1(blk[1]); + blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; + blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); + a = tfsG0(blk[2]); + b = tfsG1(blk[3]); + blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; + blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); + } + + function tfsClose() { + tfsKey = []; + tfsM = [ [], [], [], [] ]; + } + + function tfsEncrypt(data, offset) { + dataBytes = data; + dataOffset = offset; + var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[0], + getW(dataBytes, dataOffset + 4) ^ tfsKey[1], + getW(dataBytes, dataOffset + 8) ^ tfsKey[2], + getW(dataBytes, dataOffset + 12) ^ tfsKey[3] ]; + for ( var j = 0; j < 8; j++) { + tfsFrnd(j, blk); } + setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]); + setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]); + setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]); + setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]); + dataOffset += 16; + return dataBytes; + } + + function tfsDecrypt(data, offset) { + dataBytes = data; + dataOffset = offset; + var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[4], + getW(dataBytes, dataOffset + 4) ^ tfsKey[5], + getW(dataBytes, dataOffset + 8) ^ tfsKey[6], + getW(dataBytes, dataOffset + 12) ^ tfsKey[7] ]; + for ( var j = 7; j >= 0; j--) { + tfsIrnd(j, blk); + } + setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]); + setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]); + setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]); + setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]); + dataOffset += 16; + } + + // added by Recurity Labs + function tfsFinal() { + return dataBytes; + } + + return { + name : "twofish", + blocksize : 128 / 8, + open : tfsInit, + close : tfsClose, + encrypt : tfsEncrypt, + decrypt : tfsDecrypt, + // added by Recurity Labs + finalize: tfsFinal + }; +} + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// RSA implementation + +function SecureRandom(){ + function nextBytes(byteArray){ + for(var n = 0; n < byteArray.length;n++){ + byteArray[n] = openpgp_crypto_getSecureRandomOctet(); + } + } + this.nextBytes = nextBytes; +} + +function RSA() { + /** + * This function uses jsbn Big Num library to decrypt RSA + * @param m + * message + * @param d + * RSA d as BigInteger + * @param p + * RSA p as BigInteger + * @param q + * RSA q as BigInteger + * @param u + * RSA u as BigInteger + * @return {BigInteger} The decrypted value of the message + */ + function decrypt(m, d, p, q, u) { + var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p); + var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q); + util.print_debug("rsa.js decrypt\nxpn:"+util.hexstrdump(xp.toMPI())+"\nxqn:"+util.hexstrdump(xq.toMPI())); + + var t = xq.subtract(xp); + if (t[0] == 0) { + t = xp.subtract(xq); + t = t.multiply(u).mod(q); + t = q.subtract(t); + } else { + t = t.multiply(u).mod(q); + } + return t.multiply(p).add(xp); + } + + /** + * encrypt message + * @param m message as BigInteger + * @param e public MPI part as BigInteger + * @param n public MPI part as BigInteger + * @return BigInteger + */ + function encrypt(m,e,n) { + return m.modPowInt(e, n); + } + + /* Sign and Verify */ + function sign(m,d,n) { + return m.modPow(d, n); + } + + function verify(x,e,n) { + return x.modPowInt(e, n); + } + + // "empty" RSA key constructor + function keyObject() { + this.n = null; + this.e = 0; + this.ee = null; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.u = null; + } + + // Generate a new random private key B bits long, using public expt E + function generate(B,E) { + var key = new keyObject(); + var rng = new SecureRandom(); + var qs = B>>1; + key.e = parseInt(E,16); + key.ee = new BigInteger(E,16); + for(;;) { + for(;;) { + key.p = new BigInteger(B-qs,1,rng); + if(key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) break; + } + for(;;) { + key.q = new BigInteger(qs,1,rng); + if(key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) break; + } + if(key.p.compareTo(key.q) <= 0) { + var t = key.p; + key.p = key.q; + key.q = t; + } + var p1 = key.p.subtract(BigInteger.ONE); + var q1 = key.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if(phi.gcd(key.ee).compareTo(BigInteger.ONE) == 0) { + key.n = key.p.multiply(key.q); + key.d = key.ee.modInverse(phi); + key.dmp1 = key.d.mod(p1); + key.dmq1 = key.d.mod(q1); + key.u = key.p.modInverse(key.q); + break; + } + } + return key; + } + + this.encrypt = encrypt; + this.decrypt = decrypt; + this.verify = verify; + this.sign = sign; + this.generate = generate; + this.keyObject = keyObject; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// A Digital signature algorithm implementation + +function DSA() { + // s1 = ((g**s) mod p) mod q + // s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q) + function sign(hashalgo, m, g, p, q, x) { + // If the output size of the chosen hash is larger than the number of + // bits of q, the hash result is truncated to fit by taking the number + // of leftmost bits equal to the number of bits of q. This (possibly + // truncated) hash function result is treated as a number and used + // directly in the DSA signature algorithm. + var hashed_data = util.getLeftNBits(openpgp_crypto_hashData(hashalgo,m),q.bitLength()); + var hash = new BigInteger(util.hexstrdump(hashed_data), 16); + var k = openpgp_crypto_getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); + var s1 = (g.modPow(k,p)).mod(q); + var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); + var result = new Array(); + result[0] = s1.toMPI(); + result[1] = s2.toMPI(); return result; } + function select_hash_algorithm(q) { + var usersetting = openpgp.config.config.prefer_hash_algorithm; + /* + * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash + * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash + * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash + * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash + */ + switch (Math.round(q.bitLength() / 8)) { + case 20: // 1024 bit + if (usersetting != 2 && + usersetting > 11 && + usersetting != 10 && + usersetting < 8) + return 2; // prefer sha1 + return usersetting; + case 28: // 2048 bit + if (usersetting > 11 && + usersetting < 8) + return 11; + return usersetting; + case 32: // 4096 bit // prefer sha224 + if (usersetting > 10 && + usersetting < 8) + return 8; // prefer sha256 + return usersetting; + default: + util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"); + return null; + + } + } + this.select_hash_algorithm = select_hash_algorithm; + function verify(hashalgo, s1,s2,m,p,q,g,y) { + var hashed_data = util.getLeftNBits(openpgp_crypto_hashData(hashalgo,m),q.bitLength()); + var hash = new BigInteger(util.hexstrdump(hashed_data), 16); + if (BigInteger.ZERO.compareTo(s1) > 0 || + s1.compareTo(q) > 0 || + BigInteger.ZERO.compareTo(s2) > 0 || + s2.compareTo(q) > 0) { + util.print_error("invalid DSA Signature"); + return null; + } + var w = s2.modInverse(q); + var u1 = hash.multiply(w).mod(q); + var u2 = s1.multiply(w).mod(q); + return g.modPow(u1,p).multiply(y.modPow(u2,p)).mod(p).mod(q); + } - function getSigningKey() { - if ((this.privateKeyPacket.publicKey.publicKeyAlgorithm == 17 || - this.privateKeyPacket.publicKey.publicKeyAlgorithm != 2) - && this.privateKeyPacket.publicKey.verifyKey() == 3) - return this.privateKeyPacket; - else if (this.privateKeyPacket.publicKey.version == 4) // V3 keys MUST NOT have subkeys. - for (var j = 0; j < this.privateKeyPacket.subKeys.length; j++) { - if ((this.privateKeyPacket.subKeys[j].publicKey.publicKeyAlgorithm == 17 || - this.privateKeyPacket.subKeys[j].publicKey.publicKeyAlgorithm != 2) && - this.privateKeyPacket.subKeys[j].publicKey.verifyKey() == 3) - return this.privateKeyPacket.subKeys[j]; + /* + * unused code. This can be used as a start to write a key generator + * function. + + function generateKey(bitcount) { + var qi = new BigInteger(bitcount, primeCenterie); + var pi = generateP(q, 512); + var gi = generateG(p, q, bitcount); + var xi; + do { + xi = new BigInteger(q.bitCount(), rand); + } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1); + var yi = g.modPow(x, p); + return {x: xi, q: qi, p: pi, g: gi, y: yi}; + } + + function generateP(q, bitlength, randomfn) { + if (bitlength % 64 != 0) { + return false; + } + var pTemp; + var pTemp2; + do { + pTemp = randomfn(bitcount, true); + pTemp2 = pTemp.subtract(BigInteger.ONE); + pTemp = pTemp.subtract(pTemp2.remainder(q)); + } while (!pTemp.isProbablePrime(primeCenterie) || pTemp.bitLength() != l); + return pTemp; + } + + function generateG(p, q, bitlength, randomfn) { + var aux = p.subtract(BigInteger.ONE); + var pow = aux.divide(q); + var gTemp; + do { + gTemp = randomfn(bitlength); + } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1); + return gTemp.modPow(pow, p); + } + + function generateK(q, bitlength, randomfn) { + var tempK; + do { + tempK = randomfn(bitlength, false); + } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1); + return tempK; + } + + function generateR(q,p) { + k = generateK(q); + var r = g.modPow(k, p).mod(q); + return r; + } + + function generateS(hashfn,k,r,m,q,x) { + var hash = hashfn(m); + s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q); + return s; + } */ + this.sign = sign; + this.verify = verify; + // this.generate = generateKey; +} +/* + * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) + * All Rights Reserved. + * + * Modified by Recurity Labs GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * In addition, the following condition applies: + * + * All redistributions must retain an intact copy of this copyright notice + * and disclaimer. + */ + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// ElGamal implementation + +function Elgamal() { + + function encrypt(m,g,p,y) { + // choose k in {2,...,p-2} + var two = BigInteger.ONE.add(BigInteger.ONE); + var pMinus2 = p.subtract(two); + var k = openpgp_crypto_getRandomBigIntegerInRange(two, pMinus2); + var k = k.mod(pMinus2).add(BigInteger.ONE); + var c = new Array(); + c[0] = g.modPow(k, p); + c[1] = y.modPow(k, p).multiply(m).mod(p).toMPI(); + c[0] = c[0].toMPI(); + return c; + } + + function decrypt(c1,c2,p,x) { + util.print_debug("Elgamal Decrypt:\nc1:"+util.hexstrdump(c1.toMPI())+"\n"+ + "c2:"+util.hexstrdump(c2.toMPI())+"\n"+ + "p:"+util.hexstrdump(p.toMPI())+"\n"+ + "x:"+util.hexstrdump(x.toMPI())); + return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p); + //var c = c1.pow(x).modInverse(p); // c0^-a mod p + //return c.multiply(c2).mod(p); + } + + // signing and signature verification using Elgamal is not required by OpenPGP. + this.encrypt = encrypt; + this.decrypt = decrypt; +}/* + * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) + * All Rights Reserved. + * + * Modified by Recurity Labs GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * In addition, the following condition applies: + * + * All redistributions must retain an intact copy of this copyright notice + * and disclaimer. + */ +// Extended JavaScript BN functions, required for RSA private ops. + +// Version 1.1: new BigInteger("0", 10) returns "proper" zero +// Version 1.2: square() API, isProbablePrime fix + +// (public) +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + //if((d&0x80) != 0) d |= -256; + //if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [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,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +/* added by Recurity Labs */ + +function nbits(x) { + var n = 1, t; + if ((t = x >>> 16) != 0) { + x = t; + n += 16; + } + if ((t = x >> 8) != 0) { + x = t; + n += 8; + } + if ((t = x >> 4) != 0) { + x = t; + n += 4; + } + if ((t = x >> 2) != 0) { + x = t; + n += 2; + } + if ((t = x >> 1) != 0) { + x = t; + n += 1; + } + return n; +} + +function bnToMPI () { + var ba = this.toByteArray(); + var size = (ba.length-1)*8+nbits(ba[0]); + var result = ""; + result += String.fromCharCode((size & 0xFF00) >> 8); + result += String.fromCharCode(size & 0xFF); + result += util.bin2str(ba); + return result; +} +/* END of addition */ + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; +BigInteger.prototype.toMPI = bnToMPI; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// The GPG4Browsers symmetric crypto interface + +/** + * Symmetrically encrypts data using prefixedrandom, a key with length + * depending on the algorithm in openpgp_cfb mode with or without resync + * (MDC style) + * @param prefixrandom secure random bytes as string in length equal to the + * block size of the algorithm used (use openpgp_crypto_getPrefixRandom(algo) + * to retrieve that string + * @param algo [Integer] algorithm to use (see RFC4880 9.2) + * @param key [String] key as string. length is depending on the algorithm used + * @param data [String] data to encrypt + * @param openpgp_cfb [boolean] + * @return [String] encrypted data + */ +function openpgp_crypto_symmetricEncrypt(prefixrandom, algo, key, data, openpgp_cfb) { + switch(algo) { + case 0: // Plaintext or unencrypted data + return data; // blockcipherencryptfn, plaintext, block_size, key + case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) + return openpgp_cfb_encrypt(prefixrandom, desede, data,8,key, openpgp_cfb).substring(0, data.length + 10); + case 3: // CAST5 (128 bit key, as per [RFC2144]) + return openpgp_cfb_encrypt(prefixrandom, cast5_encrypt, data,8,key, openpgp_cfb).substring(0, data.length + 10); + case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] + return openpgp_cfb_encrypt(prefixrandom, BFencrypt, data,8,key, openpgp_cfb).substring(0, data.length + 10); + case 7: // AES with 128-bit key [AES] + case 8: // AES with 192-bit key + case 9: // AES with 256-bit key + return openpgp_cfb_encrypt(prefixrandom, AESencrypt, data, 16, keyExpansion(key), openpgp_cfb).substring(0, data.length + 18); + case 10: // Twofish with 256-bit key [TWOFISH] + return openpgp_cfb_encrypt(prefixrandom, TFencrypt, data,16, key, openpgp_cfb).substring(0, data.length + 18); + case 1: // IDEA [IDEA] + util.print_error("IDEA Algorithm not implemented"); + return null; + default: + return null; + } +} + +/** + * Symmetrically decrypts data using a key with length depending on the + * algorithm in openpgp_cfb mode with or without resync (MDC style) + * @param algo [Integer] algorithm to use (see RFC4880 9.2) + * @param key [String] key as string. length is depending on the algorithm used + * @param data [String] data to be decrypted + * @param openpgp_cfb [boolean] if true use the resync (for encrypteddata); + * otherwise use without the resync (for MDC encrypted data) + * @return [String] plaintext data + */ +function openpgp_crypto_symmetricDecrypt(algo, key, data, openpgp_cfb) { + util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nalgo:"+algo+"\nencrypteddata:",data); + var n = 0; + if (!openpgp_cfb) + n = 2; + switch(algo) { + case 0: // Plaintext or unencrypted data + return data; + case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) + return openpgp_cfb_decrypt(desede, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); + case 3: // CAST5 (128 bit key, as per [RFC2144]) + return openpgp_cfb_decrypt(cast5_encrypt, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); + case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] + return openpgp_cfb_decrypt(BFencrypt, 8, key, data, openpgp_cfb).substring(n, (data.length+n)-10); + case 7: // AES with 128-bit key [AES] + case 8: // AES with 192-bit key + case 9: // AES with 256-bit key + return openpgp_cfb_decrypt(AESencrypt, 16, keyExpansion(key), data, openpgp_cfb).substring(n, (data.length+n)-18); + case 10: // Twofish with 256-bit key [TWOFISH] + var result = openpgp_cfb_decrypt(TFencrypt, 16, key, data, openpgp_cfb).substring(n, (data.length+n)-18); + return result; + case 1: // IDEA [IDEA] + util.print_error(""+ (algo == 1 ? "IDEA Algorithm not implemented" : "Twofish Algorithm not implemented")); + return null; + default: + } + return null; +}// Modified by Recurity Labs GmbH + +// modified version of http://www.hanewin.net/encrypt/PGdecode.js: + +/* OpenPGP encryption using RSA/AES + * Copyright 2005-2006 Herbert Hanewinkel, www.haneWIN.de + * version 2.0, check www.haneWIN.de for the latest version + + * This software is provided as-is, without express or implied warranty. + * Permission to use, copy, modify, distribute or sell this software, with or + * without fee, for any purpose and by any individual or organization, is hereby + * granted, provided that the above copyright notice and this paragraph appear + * in all copies. Distribution as a part of an application or binary must + * include the above copyright notice in the documentation and/or other + * materials provided with the application or distribution. + */ + +// -------------------------------------- +/** + * This function encrypts a given with the specified prefixrandom + * using the specified blockcipher to encrypt a message + * @param prefixrandom random bytes of block_size length provided + * as a string to be used in prefixing the data + * @param blockcipherfn the algorithm encrypt function to encrypt + * data in one block_size encryption. The function must be + * specified as blockcipherfn([integer_array(integers 0..255)] + * block,[integer_array(integers 0..255)] key) returning an + * array of bytes (integers 0..255) + * @param block_size the block size in bytes of the algorithm used + * @param plaintext data to be encrypted provided as a string + * @param key key to be used to encrypt the data as + * integer_array(integers 0..255)]. This will be passed to the + * blockcipherfn + * @param resync a boolean value specifying if a resync of the + * IV should be used or not. The encrypteddatapacket uses the + * "old" style with a resync. Encryption within an + * encryptedintegrityprotecteddata packet is not resyncing the IV. + * @return a string with the encrypted data + */ +function openpgp_cfb_encrypt(prefixrandom, blockcipherencryptfn, plaintext, block_size, key, resync) { + var FR = new Array(block_size); + var FRE = new Array(block_size); + + prefixrandom = prefixrandom + prefixrandom.charAt(block_size-2) +prefixrandom.charAt(block_size-1); + util.print_debug("prefixrandom:"+util.hexstrdump(prefixrandom)); + var ciphertext = ""; + // 1. The feedback register (FR) is set to the IV, which is all zeros. + for (var i = 0; i < block_size; i++) FR[i] = 0; + + // 2. FR is encrypted to produce FRE (FR Encrypted). This is the + // encryption of an all-zero value. + FRE = blockcipherencryptfn(FR, key); + // 3. FRE is xored with the first BS octets of random data prefixed to + // the plaintext to produce C[1] through C[BS], the first BS octets + // of ciphertext. + for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ prefixrandom.charCodeAt(i)); + + // 4. FR is loaded with C[1] through C[BS]. + for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); + + // 5. FR is encrypted to produce FRE, the encryption of the first BS + // octets of ciphertext. + FRE = blockcipherencryptfn(FR, key); + + // 6. The left two octets of FRE get xored with the next two octets of + // data that were prefixed to the plaintext. This produces C[BS+1] + // and C[BS+2], the next two octets of ciphertext. + ciphertext += String.fromCharCode(FRE[0] ^ prefixrandom.charCodeAt(block_size)); + ciphertext += String.fromCharCode(FRE[1] ^ prefixrandom.charCodeAt(block_size+1)); + + if (resync) { + // 7. (The resync step) FR is loaded with C3-C10. + for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i+2); + } else { + for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); + } + // 8. FR is encrypted to produce FRE. + FRE = blockcipherencryptfn(FR, key); + + if (resync) { + // 9. FRE is xored with the first 8 octets of the given plaintext, now + // that we have finished encrypting the 10 octets of prefixed data. + // This produces C11-C18, the next 8 octets of ciphertext. + for (var i = 0; i < block_size; i++) + ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); + for(n=block_size+2; n < plaintext.length; n+=block_size) { + // 10. FR is loaded with C11-C18 + for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(n+i); + + // 11. FR is encrypted to produce FRE. + FRE = blockcipherencryptfn(FR, key); + + // 12. FRE is xored with the next 8 octets of plaintext, to produce the + // next 8 octets of ciphertext. These are loaded into FR and the + // process is repeated until the plaintext is used up. + for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt((n-2)+i)); + } + } + else { + plaintext = " "+plaintext; + // 9. FRE is xored with the first 8 octets of the given plaintext, now + // that we have finished encrypting the 10 octets of prefixed data. + // This produces C11-C18, the next 8 octets of ciphertext. + for (var i = 2; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); + var tempCiphertext = ciphertext.substring(0,2*block_size).split(''); + var tempCiphertextString = ciphertext.substring(block_size); + for(n=block_size; n block_size*pos) { + var encblock = blockcipherencryptfn(blockc, key); + blocki = plaintext.substring((pos*block_size),(pos*block_size)+block_size); + for (var i=0; i < blocki.length; i++) + tempBlock.push(String.fromCharCode(blocki.charCodeAt(i) ^ encblock[i])); + blockc = tempBlock.join(''); + tempBlock = []; + cyphertext.push(blockc); + pos++; + } + return cyphertext.join(''); +} + +function normal_cfb_decrypt(blockcipherencryptfn, block_size, key, ciphertext, iv) { + var blockp =""; + var pos = 0; + var plaintext = []; + var offset = 0; + if (iv == null) + for (var i = 0; i < block_size; i++) blockp += String.fromCharCode(0); + else + blockp = iv.substring(0,block_size); + while (ciphertext.length > (block_size*pos)) { + var decblock = blockcipherencryptfn(blockp, key); + blockp = ciphertext.substring((pos*(block_size))+offset,(pos*(block_size))+(block_size)+offset); + for (var i=0; i < blockp.length; i++) { + plaintext.push(String.fromCharCode(blockp.charCodeAt(i) ^ decblock[i])); + } + pos++; + } + + return plaintext.join(''); +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// The GPG4Browsers crypto interface + +/** + * Encrypts data using the specified public key multiprecision integers + * and the specified algorithm. + * @param algo [Integer] Algorithm to be used (See RFC4880 9.1) + * @param publicMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers + * @param data [openpgp_type_mpi] data to be encrypted as MPI + * @return [Object] if RSA an openpgp_type_mpi; if elgamal encryption an array of two + * openpgp_type_mpi is returned; otherwise null + */ +function openpgp_crypto_asymetricEncrypt(algo, publicMPIs, data) { + switch(algo) { + case 1: // RSA (Encrypt or Sign) [HAC] + case 2: // RSA Encrypt-Only [HAC] + case 3: // RSA Sign-Only [HAC] + var rsa = new RSA(); + var n = publicMPIs[0].toBigInteger(); + var e = publicMPIs[1].toBigInteger(); + var m = data.toBigInteger(); + return rsa.encrypt(m,e,n).toMPI(); + case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + var elgamal = new Elgamal(); + var p = publicMPIs[0].toBigInteger(); + var g = publicMPIs[1].toBigInteger(); + var y = publicMPIs[2].toBigInteger(); + var m = data.toBigInteger(); + return elgamal.encrypt(m,g,p,y); + default: + return null; + } +} + +/** + * Decrypts data using the specified public key multiprecision integers of the private key, + * the specified secretMPIs of the private key and the specified algorithm. + * @param algo [Integer] Algorithm to be used (See RFC4880 9.1) + * @param publicMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers of the public key part of the private key + * @param secretMPIs [Array[openpgp_type_mpi]] algorithm dependent multiprecision integers of the private key used + * @param data [openpgp_type_mpi] data to be encrypted as MPI + * @return [BigInteger] returns a big integer containing the decrypted data; otherwise null + */ + +function openpgp_crypto_asymetricDecrypt(algo, publicMPIs, secretMPIs, dataMPIs) { + switch(algo) { + case 1: // RSA (Encrypt or Sign) [HAC] + case 2: // RSA Encrypt-Only [HAC] + case 3: // RSA Sign-Only [HAC] + var rsa = new RSA(); + var d = secretMPIs[0].toBigInteger(); + var p = secretMPIs[1].toBigInteger(); + var q = secretMPIs[2].toBigInteger(); + var u = secretMPIs[3].toBigInteger(); + var m = dataMPIs[0].toBigInteger(); + return rsa.decrypt(m, d, p, q, u); + case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + var elgamal = new Elgamal(); + var x = secretMPIs[0].toBigInteger(); + var c1 = dataMPIs[0].toBigInteger(); + var c2 = dataMPIs[1].toBigInteger(); + var p = publicMPIs[0].toBigInteger(); + return elgamal.decrypt(c1,c2,p,x); + default: return null; } - function getPreferredSignatureHashAlgorithm() { - var pkey = this.getSigningKey(); - if (pkey == null) { - util.print_error("private key is for encryption only! Cannot create a signature.") - return null; - } - if (pkey.publicKey.publicKeyAlgorithm == 17) { - var dsa = new DSA(); - return dsa.select_hash_algorithm(pkey.publicKey.MPIs[1].toBigInteger()); // q - } - return openpgp.config.config.prefer_hash_algorithm; - - } +} - function decryptSecretMPIs(str_passphrase) { - return this.privateKeyPacket.decryptSecretMPIs(str_passphrase); - } - - function getFingerprint() { - return this.privateKeyPacket.publicKey.getFingerprint(); +/** + * generate random byte prefix as string for the specified algorithm + * @param algo [Integer] algorithm to use (see RFC4880 9.2) + * @return [String] random bytes with length equal to the block + * size of the cipher + */ +function openpgp_crypto_getPrefixRandom(algo) { + switch(algo) { + case 2: + case 3: + case 4: + return openpgp_crypto_getRandomBytes(8); + case 7: + case 8: + case 9: + case 10: + return openpgp_crypto_getRandomBytes(16); + default: + return null; } +} - // TODO need to implement this - function revoke() { +/** + * retrieve the MDC prefixed bytes by decrypting them + * @param algo [Integer] algorithm to use (see RFC4880 9.2) + * @param key [String] key as string. length is depending on the algorithm used + * @param data [String] encrypted data where the prefix is decrypted from + * @return [String] plain text data of the prefixed data + */ +function openpgp_crypto_MDCSystemBytes(algo, key, data) { + util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nencrypteddata:",data); + switch(algo) { + case 0: // Plaintext or unencrypted data + return data; + case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) + return openpgp_cfb_mdc(desede, 8, key, data, openpgp_cfb); + case 3: // CAST5 (128 bit key, as per [RFC2144]) + return openpgp_cfb_mdc(cast5_encrypt, 8, key, data); + case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] + return openpgp_cfb_mdc(BFencrypt, 8, key, data); + case 7: // AES with 128-bit key [AES] + case 8: // AES with 192-bit key + case 9: // AES with 256-bit key + return openpgp_cfb_mdc(AESencrypt, 16, keyExpansion(key), data); + case 10: + return openpgp_cfb_mdc(TFencrypt, 16, key, data); + case 1: // IDEA [IDEA] + util.print_error(""+ (algo == 1 ? "IDEA Algorithm not implemented" : "Twofish Algorithm not implemented")); + return null; + default: + } + return null; +} +/** + * Generating a session key for the specified symmetric algorithm + * @param algo [Integer] algorithm to use (see RFC4880 9.2) + * @return [String] random bytes as a string to be used as a key + */ +function openpgp_crypto_generateSessionKey(algo) { + switch (algo) { + case 2: // TripleDES (DES-EDE, [SCHNEIER] [HAC] - 168 bit key derived from 192) + case 8: // AES with 192-bit key + return openpgp_crypto_getRandomBytes(24); + case 3: // CAST5 (128 bit key, as per [RFC2144]) + case 4: // Blowfish (128 bit key, 16 rounds) [BLOWFISH] + case 7: // AES with 128-bit key [AES] + util.print_debug("length = 16:\n"+util.hexstrdump(openpgp_crypto_getRandomBytes(16))); + return openpgp_crypto_getRandomBytes(16); + case 9: // AES with 256-bit key + case 10:// Twofish with 256-bit key [TWOFISH] + return openpgp_crypto_getRandomBytes(32); + } + return null; +} + +/** + * + * @param algo [Integer] public key algorithm + * @param hash_algo [Integer] hash algorithm + * @param msg_MPIs [Array[openpgp_type_mpi]] signature multiprecision integers + * @param publickey_MPIs [Array[openpgp_type_mpi]] public key multiprecision integers + * @param data [String] data on where the signature was computed on. + * @return true if signature (sig_data was equal to data over hash) + */ +function openpgp_crypto_verifySignature(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { + var calc_hash = openpgp_crypto_hashData(hash_algo, data); + switch(algo) { + case 1: // RSA (Encrypt or Sign) [HAC] + case 2: // RSA Encrypt-Only [HAC] + case 3: // RSA Sign-Only [HAC] + var rsa = new RSA(); + var n = publickey_MPIs[0].toBigInteger(); + var e = publickey_MPIs[1].toBigInteger(); + var x = msg_MPIs[0].toBigInteger(); + var dopublic = rsa.verify(x,e,n); + var hash = openpgp_encoding_emsa_pkcs1_decode(hash_algo,dopublic.toMPI().substring(2)); + if (hash == -1) { + util.print_error("PKCS1 padding in message or key incorrect. Aborting..."); + return false; + } + return hash == calc_hash; + case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + util.print_error("signing with Elgamal is not defined in the OpenPGP standard."); + return null; + case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] + var dsa = new DSA(); + var s1 = msg_MPIs[0].toBigInteger(); + var s2 = msg_MPIs[1].toBigInteger(); + var p = publickey_MPIs[0].toBigInteger(); + var q = publickey_MPIs[1].toBigInteger(); + var g = publickey_MPIs[2].toBigInteger(); + var y = publickey_MPIs[3].toBigInteger(); + var m = data; + var dopublic = dsa.verify(hash_algo,s1,s2,m,p,q,g,y); + return dopublic.compareTo(s1) == 0; + default: + return null; } - - /** - * extracts the public key part - * @return {String} OpenPGP armored text containing the public key - * returns null if no sufficient data to extract public key - */ - function extractPublicKey() { - // add public key - var key = this.privateKeyPacket.publicKey.header + this.privateKeyPacket.publicKey.data; - for (var i = 0; i < this.userIds.length; i++) { - // verify userids - if (this.userIds[i].certificationSignatures.length === 0) { - util.print_error("extractPublicKey - missing certification signatures"); - return null; - } - var userIdPacket = new openpgp_packet_userid(); - // add userids - key += userIdPacket.write_packet(this.userIds[i].text); - for (var j = 0; j < this.userIds[i].certificationSignatures.length; j++) { - var certSig = this.userIds[i].certificationSignatures[j]; - // add signatures - key += openpgp_packet.write_packet_header(2, certSig.data.length) + certSig.data; - } - } - for (var k = 0; k < this.subKeys.length; k++) { - var pubSubKey = this.subKeys[k].publicKey; - // add public subkey package - key += openpgp_packet.write_old_packet_header(14, pubSubKey.data.length) + pubSubKey.data; - var subKeySig = this.subKeys[k].subKeySignature; - if (subKeySig !== null) { - // add subkey signature - key += openpgp_packet.write_packet_header(2, subKeySig.data.length) + subKeySig.data; - } else { - util.print_error("extractPublicKey - missing subkey signature"); - return null; - } - } - var publicArmored = openpgp_encoding_armor(4, key); - return publicArmored; - } - - this.extractPublicKey = extractPublicKey; - this.getSigningKey = getSigningKey; - this.getFingerprint = getFingerprint; - this.getPreferredSignatureHashAlgorithm = getPreferredSignatureHashAlgorithm; - this.read_nodes = read_nodes; - this.decryptSecretMPIs = decryptSecretMPIs; - this.getSubKeyIds = getSubKeyIds; - this.getKeyId = getKeyId; -}// GPG4Browsers - An OpenPGP implementation in javascript +} + +/** + * Create a signature on data using the specified algorithm + * @param hash_algo [Integer] hash algorithm to use (See RFC4880 9.4) + * @param algo [Integer] asymmetric cipher algorithm to use (See RFC4880 9.1) + * @param publicMPIs [Array[openpgp_type_mpi]] public key multiprecision integers of the private key + * @param secretMPIs [Array[openpgp_type_mpi]] private key multiprecision integers which is used to sign the data + * @param data [String] data to be signed + * @return [String or openpgp_type_mpi] + */ +function openpgp_crypto_signData(hash_algo, algo, publicMPIs, secretMPIs, data) { + + switch(algo) { + case 1: // RSA (Encrypt or Sign) [HAC] + case 2: // RSA Encrypt-Only [HAC] + case 3: // RSA Sign-Only [HAC] + var rsa = new RSA(); + var d = secretMPIs[0].toBigInteger(); + var n = publicMPIs[0].toBigInteger(); + var m = openpgp_encoding_emsa_pkcs1_encode(hash_algo, data,publicMPIs[0].mpiByteLength); + util.print_debug("signing using RSA"); + return rsa.sign(m, d, n).toMPI(); + case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] + var dsa = new DSA(); + util.print_debug("DSA Sign: q size in Bytes:"+publicMPIs[1].getByteLength()); + var p = publicMPIs[0].toBigInteger(); + var q = publicMPIs[1].toBigInteger(); + var g = publicMPIs[2].toBigInteger(); + var y = publicMPIs[3].toBigInteger(); + var x = secretMPIs[0].toBigInteger(); + var m = data; + var result = dsa.sign(hash_algo,m, g, p, q, x); + util.print_debug("signing using DSA\n result:"+util.hexstrdump(result[0])+"|"+util.hexstrdump(result[1])); + return result[0]+result[1]; + case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + util.print_debug("signing with Elgamal is not defined in the OpenPGP standard."); + return null; + default: + return null; + } +} + +/** + * create a hash on the specified data using the specified algorithm + * @param algo [Integer] hash algorithm type (see RFC4880 9.4) + * @param data [String] data to be hashed + * @return [String] hash value + */ +function openpgp_crypto_hashData(algo, data) { + var hash = null; + switch(algo) { + case 1: // - MD5 [HAC] + hash = MD5(data); + break; + case 2: // - SHA-1 [FIPS180] + hash = str_sha1(data); + break; + case 3: // - RIPE-MD/160 [HAC] + hash = RMDstring(data); + break; + case 8: // - SHA256 [FIPS180] + hash = str_sha256(data); + break; + case 9: // - SHA384 [FIPS180] + hash = str_sha384(data); + break; + case 10:// - SHA512 [FIPS180] + hash = str_sha512(data); + break; + case 11:// - SHA224 [FIPS180] + hash = str_sha224(data); + default: + break; + } + return hash; +} + +/** + * returns the hash size in bytes of the specified hash algorithm type + * @param algo [Integer] hash algorithm type (See RFC4880 9.4) + * @return [Integer] size in bytes of the resulting hash + */ +function openpgp_crypto_getHashByteLength(algo) { + var hash = null; + switch(algo) { + case 1: // - MD5 [HAC] + return 16; + case 2: // - SHA-1 [FIPS180] + case 3: // - RIPE-MD/160 [HAC] + return 20; + case 8: // - SHA256 [FIPS180] + return 32; + case 9: // - SHA384 [FIPS180] + return 48 + case 10:// - SHA512 [FIPS180] + return 64; + case 11:// - SHA224 [FIPS180] + return 28; + } + return null; +} + +/** + * retrieve secure random byte string of the specified length + * @param length [Integer] length in bytes to generate + * @return [String] random byte string + */ +function openpgp_crypto_getRandomBytes(length) { + var result = ''; + for (var i = 0; i < length; i++) { + result += String.fromCharCode(openpgp_crypto_getSecureRandomOctet()); + } + return result; +} + +/** + * return a pseudo-random number in the specified range + * @param from [Integer] min of the random number + * @param to [Integer] max of the random number (max 32bit) + * @return [Integer] a pseudo random number + */ +function openpgp_crypto_getPseudoRandom(from, to) { + return Math.round(Math.random()*(to-from))+from; +} + +/** + * return a secure random number in the specified range + * @param from [Integer] min of the random number + * @param to [Integer] max of the random number (max 32bit) + * @return [Integer] a secure random number + */ +function openpgp_crypto_getSecureRandom(from, to) { + var buf = new Uint32Array(1); + window.crypto.getRandomValues(buf); + var bits = ((to-from)).toString(2).length; + while ((buf[0] & (Math.pow(2, bits) -1)) > (to-from)) + window.crypto.getRandomValues(buf); + return from+(Math.abs(buf[0] & (Math.pow(2, bits) -1))); +} + +function openpgp_crypto_getSecureRandomOctet() { + var buf = new Uint32Array(1); + window.crypto.getRandomValues(buf); + return buf[0] & 0xFF; +} + +/** + * create a secure random big integer of bits length + * @param bits [Integer] bit length of the MPI to create + * @return [BigInteger] resulting big integer + */ +function openpgp_crypto_getRandomBigInteger(bits) { + if (bits < 0) + return null; + var numBytes = Math.floor((bits+7)/8); + + var randomBits = openpgp_crypto_getRandomBytes(numBytes); + if (bits % 8 > 0) { + + randomBits = String.fromCharCode( + (Math.pow(2,bits % 8)-1) & + randomBits.charCodeAt(0)) + + randomBits.substring(1); + } + return new openpgp_type_mpi().create(randomBits).toBigInteger(); +} + +function openpgp_crypto_getRandomBigIntegerInRange(min, max) { + if (max.compareTo(min) <= 0) + return; + var range = max.subtract(min); + var r = openpgp_crypto_getRandomBigInteger(range.bitLength()); + while (r > range) { + r = openpgp_crypto_getRandomBigInteger(range.bitLength()); + } + return min.add(r); +} + + +//This is a test method to ensure that encryption/decryption with a given 1024bit RSAKey object functions as intended +function openpgp_crypto_testRSA(key){ + debugger; + var rsa = new RSA(); + var mpi = new openpgp_type_mpi(); + mpi.create(openpgp_encoding_eme_pkcs1_encode('ABABABAB', 128)); + var msg = rsa.encrypt(mpi.toBigInteger(),key.ee,key.n); + var result = rsa.decrypt(msg, key.d, key.p, key.q, key.u); +} +/** + * calls the necessary crypto functions to generate a keypair. Called directly by openpgp.js + * @keyType [int] follows OpenPGP algorithm convention. + * @numBits [int] number of bits to make the key to be generated + * @return {privateKey: [openpgp_packet_keymaterial] , publicKey: [openpgp_packet_keymaterial]} + */ +function openpgp_crypto_generateKeyPair(keyType, numBits, passphrase, s2kHash, symmetricEncryptionAlgorithm){ + var privKeyPacket; + var publicKeyPacket; + var d = new Date(); + d = d.getTime()/1000; + var timePacket = String.fromCharCode(Math.floor(d/0x1000000%0x100)) + String.fromCharCode(Math.floor(d/0x10000%0x100)) + String.fromCharCode(Math.floor(d/0x100%0x100)) + String.fromCharCode(Math.floor(d%0x100)); + switch(keyType){ + case 1: + var rsa = new RSA(); + var key = rsa.generate(numBits,"10001"); + privKeyPacket = new openpgp_packet_keymaterial().write_private_key(keyType, key, passphrase, s2kHash, symmetricEncryptionAlgorithm, timePacket); + publicKeyPacket = new openpgp_packet_keymaterial().write_public_key(keyType, key, timePacket); + break; + default: + util.print_error("Unknown keytype "+keyType) + } + return {privateKey: privKeyPacket, publicKey: publicKeyPacket}; +} +// GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // // This library is free software; you can redistribute it and/or @@ -12456,6 +9569,421 @@ function openpgp_msg_privatekey() { // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +/** + * GPG4Browsers Core interface. A single instance is hold + * from the beginning. To use this library call "openpgp.init()" + * @alias openpgp + * @class + * @classdesc Main Openpgp.js class. Use this to initiate and make all calls to this library. + */ +function _openpgp () { + this.tostring = ""; + + /** + * initializes the library: + * - reading the keyring from local storage + * - reading the config from local storage + * @return [void] + */ + function init() { + this.config = new openpgp_config(); + this.config.read(); + this.keyring = new openpgp_keyring(); + this.keyring.init(); + } + + /** + * reads several publicKey objects from a ascii armored + * representation an returns openpgp_msg_publickey packets + * @param {String} armoredText OpenPGP armored text containing + * the public key(s) + * @return {Array[openpgp_msg_publickey]} on error the function + * returns null + */ + function read_publicKey(armoredText) { + var mypos = 0; + var publicKeys = new Array(); + var publicKeyCount = 0; + var input = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')).openpgp; + var l = input.length; + while (mypos != input.length) { + var first_packet = openpgp_packet.read_packet(input, mypos, l); + // public key parser + if (input[mypos].charCodeAt() == 0x99 || first_packet.tagType == 6) { + publicKeys[publicKeyCount] = new openpgp_msg_publickey(); + publicKeys[publicKeyCount].header = input.substring(mypos,mypos+3); + if (input[mypos].charCodeAt() == 0x99) { + // parse the length and read a tag6 packet + mypos++; + var l = (input[mypos++].charCodeAt() << 8) + | input[mypos++].charCodeAt(); + publicKeys[publicKeyCount].publicKeyPacket = new openpgp_packet_keymaterial(); + publicKeys[publicKeyCount].publicKeyPacket.header = publicKeys[publicKeyCount].header; + publicKeys[publicKeyCount].publicKeyPacket.read_tag6(input, mypos, l); + mypos += publicKeys[publicKeyCount].publicKeyPacket.packetLength; + mypos += publicKeys[publicKeyCount].read_nodes(publicKeys[publicKeyCount].publicKeyPacket, input, mypos, (input.length - mypos)); + } else { + publicKeys[publicKeyCount] = new openpgp_msg_publickey(); + publicKeys[publicKeyCount].publicKeyPacket = first_packet; + mypos += first_packet.headerLength+first_packet.packetLength; + mypos += publicKeys[publicKeyCount].read_nodes(first_packet, input, mypos, input.length -mypos); + } + } else { + util.print_error("no public key found!"); + return null; + } + publicKeys[publicKeyCount].data = input.substring(0,mypos); + publicKeyCount++; + } + return publicKeys; + } + + /** + * reads several privateKey objects from a ascii armored + * representation an returns openpgp_msg_privatekey objects + * @param {String} armoredText OpenPGP armored text containing + * the private key(s) + * @return {Array[openpgp_msg_privatekey]} on error the function + * returns null + */ + function read_privateKey(armoredText) { + var privateKeys = new Array(); + var privateKeyCount = 0; + var mypos = 0; + var input = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')).openpgp; + var l = input.length; + while (mypos != input.length) { + var first_packet = openpgp_packet.read_packet(input, mypos, l); + if (first_packet.tagType == 5) { + privateKeys[privateKeys.length] = new openpgp_msg_privatekey(); + mypos += first_packet.headerLength+first_packet.packetLength; + mypos += privateKeys[privateKeyCount].read_nodes(first_packet, input, mypos, l); + // other blocks + } else { + util.print_error('no block packet found!'); + return null; + } + privateKeys[privateKeyCount].data = input.substring(0,mypos); + privateKeyCount++; + } + return privateKeys; + } + + /** + * reads message packets out of an OpenPGP armored text and + * returns an array of message objects + * @param {String} armoredText text to be parsed + * @return {Array[openpgp_msg_message]} on error the function + * returns null + */ + function read_message(armoredText) { + var dearmored; + try{ + dearmored = openpgp_encoding_deArmor(armoredText.replace(/\r/g,'')); + } + catch(e){ + util.print_error('no message found!'); + return null; + } + var input = dearmored.openpgp; + var messages = new Array(); + var messageCount = 0; + var mypos = 0; + var l = input.length; + while (mypos < input.length) { + var first_packet = openpgp_packet.read_packet(input, mypos, l); + // public key parser (definition from the standard:) + // OpenPGP Message :- Encrypted Message | Signed Message | + // Compressed Message | Literal Message. + // Compressed Message :- Compressed Data Packet. + // + // Literal Message :- Literal Data Packet. + // + // ESK :- Public-Key Encrypted Session Key Packet | + // Symmetric-Key Encrypted Session Key Packet. + // + // ESK Sequence :- ESK | ESK Sequence, ESK. + // + // Encrypted Data :- Symmetrically Encrypted Data Packet | + // Symmetrically Encrypted Integrity Protected Data Packet + // + // Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data. + // + // One-Pass Signed Message :- One-Pass Signature Packet, + // OpenPGP Message, Corresponding Signature Packet. + + // Signed Message :- Signature Packet, OpenPGP Message | + // One-Pass Signed Message. + if (first_packet.tagType == 1 || + (first_packet.tagType == 2 && first_packet.signatureType < 16) || + first_packet.tagType == 3 || + first_packet.tagType == 8 || + first_packet.tagType == 9 || + first_packet.tagType == 10 || + first_packet.tagType == 11 || + first_packet.tagType == 18 || + first_packet.tagType == 19) { + messages[messages.length] = new openpgp_msg_message(); + messages[messageCount].messagePacket = first_packet; + messages[messageCount].type = dearmored.type; + // Encrypted Message + if (first_packet.tagType == 9 || + first_packet.tagType == 1 || + first_packet.tagType == 3 || + first_packet.tagType == 18) { + if (first_packet.tagType == 9) { + util.print_error("unexpected openpgp packet"); + break; + } else if (first_packet.tagType == 1) { + util.print_debug("session key found:\n "+first_packet.toString()); + var issessionkey = true; + messages[messageCount].sessionKeys = new Array(); + var sessionKeyCount = 0; + while (issessionkey) { + messages[messageCount].sessionKeys[sessionKeyCount] = first_packet; + mypos += first_packet.packetLength + first_packet.headerLength; + l -= (first_packet.packetLength + first_packet.headerLength); + first_packet = openpgp_packet.read_packet(input, mypos, l); + + if (first_packet.tagType != 1 && first_packet.tagType != 3) + issessionkey = false; + sessionKeyCount++; + } + if (first_packet.tagType == 18 || first_packet.tagType == 9) { + util.print_debug("encrypted data found:\n "+first_packet.toString()); + messages[messageCount].encryptedData = first_packet; + mypos += first_packet.packetLength+first_packet.headerLength; + l -= (first_packet.packetLength+first_packet.headerLength); + messageCount++; + + } else { + util.print_debug("something is wrong: "+first_packet.tagType); + } + + } else if (first_packet.tagType == 18) { + util.print_debug("symmetric encrypted data"); + break; + } + } else + // Signed Message + if (first_packet.tagType == 2 && first_packet.signatureType < 3) { + messages[messageCount].text = dearmored.text; + messages[messageCount].signature = first_packet; + break; + } else + // Compressed Message + // TODO: needs to be implemented. From a security perspective: this message is plaintext anyway. + if (first_packet.tagType == 8) { + util.print_error("A directly compressed message is currently not supported"); + break; + } else + // Marker Packet (Obsolete Literal Packet) (Tag 10) + // "Such a packet MUST be ignored when received." see http://tools.ietf.org/html/rfc4880#section-5.8 + if (first_packet.tagType == 10) { + // reset messages + messages.length = 0; + // continue with next packet + mypos += first_packet.packetLength + first_packet.headerLength; + l -= (first_packet.packetLength + first_packet.headerLength); + } else + // Literal Message + // TODO: needs to be implemented. From a security perspective: this message is plaintext anyway. + if (first_packet.tagType == 11) { + util.print_error("A direct literal message is currently not supported."); + break; + } + } else { + util.print_error('no message found!'); + return null; + } + } + + return messages; + } + + /** + * creates a binary string representation of an encrypted and signed message. + * The message will be encrypted with the public keys specified and signed + * with the specified private key. + * @param {obj: [openpgp_msg_privatekey]} privatekey private key to be used to sign the message + * @param {Array {obj: [openpgp_msg_publickey]}} publickeys public keys to be used to encrypt the message + * @param {String} messagetext message text to encrypt and sign + * @return {String} a binary string representation of the message which can be OpenPGP armored + */ + function write_signed_and_encrypted_message(privatekey, publickeys, messagetext) { + var result = ""; + var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); + util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); + for (var i = 0; i < publickeys.length; i++) { + var onepasssignature = new openpgp_packet_onepasssignature(); + var onepasssigstr = ""; + if (i == 0) + onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); + else + onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); + util.print_debug_hexstr_dump("onepasssigstr: |"+onepasssigstr+"|\n",onepasssigstr); + var datasignature = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"), privatekey); + util.print_debug_hexstr_dump("datasignature: |"+datasignature.openpgp+"|\n",datasignature.openpgp); + if (i == 0) { + result = onepasssigstr+literal+datasignature.openpgp; + } else { + result = onepasssigstr+result+datasignature.openpgp; + } + } + + util.print_debug_hexstr_dump("signed packet: |"+result+"|\n",result); + // signatures done.. now encryption + var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); + var result2 = ""; + + // creating session keys for each recipient + for (var i = 0; i < publickeys.length; i++) { + var pkey = publickeys[i].getEncryptionKey(); + if (pkey == null) { + util.print_error("no encryption key found! Key is for signing only."); + return null; + } + result2 += new openpgp_packet_encryptedsessionkey(). + write_pub_key_packet( + pkey.getKeyId(), + pkey.MPIs, + pkey.publicKeyAlgorithm, + openpgp.config.config.encryption_cipher, + sessionkey); + } + if (openpgp.config.config.integrity_protect) { + result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); + } else { + result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); + } + return openpgp_encoding_armor(3,result2,null,null); + } + /** + * creates a binary string representation of an encrypted message. + * The message will be encrypted with the public keys specified + * @param {Array {obj: [openpgp_msg_publickey]}} publickeys public + * keys to be used to encrypt the message + * @param {String} messagetext message text to encrypt + * @return {String} a binary string representation of the message + * which can be OpenPGP armored + */ + function write_encrypted_message(publickeys, messagetext) { + var result = ""; + var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); + util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); + result = literal; + + // signatures done.. now encryption + var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); + var result2 = ""; + + // creating session keys for each recipient + for (var i = 0; i < publickeys.length; i++) { + var pkey = publickeys[i].getEncryptionKey(); + if (pkey == null) { + util.print_error("no encryption key found! Key is for signing only."); + return null; + } + result2 += new openpgp_packet_encryptedsessionkey(). + write_pub_key_packet( + pkey.getKeyId(), + pkey.MPIs, + pkey.publicKeyAlgorithm, + openpgp.config.config.encryption_cipher, + sessionkey); + } + if (openpgp.config.config.integrity_protect) { + result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); + } else { + result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); + } + return openpgp_encoding_armor(3,result2,null,null); + } + + /** + * creates a binary string representation a signed message. + * The message will be signed with the specified private key. + * @param {obj: [openpgp_msg_privatekey]} privatekey private + * key to be used to sign the message + * @param {String} messagetext message text to sign + * @return {Object: text [String]}, openpgp: {String} a binary + * string representation of the message which can be OpenPGP + * armored(openpgp) and a text representation of the message (text). This can be directly used to OpenPGP armor the message + */ + function write_signed_message(privatekey, messagetext) { + var sig = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), privatekey); + var result = {text: messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), openpgp: sig.openpgp, hash: sig.hash}; + return openpgp_encoding_armor(2,result, null, null) + } + + /** + * generates a new key pair for openpgp. Beta stage. Currently only supports RSA keys, and no subkeys. + * @param {int} keyType to indicate what type of key to make. RSA is 1. Follows algorithms outlined in OpenPGP. + * @param {int} numBits number of bits for the key creation. (should be 1024+, generally) + * @param {string} userId assumes already in form of "User Name " + * @return {privateKey: [openpgp_msg_privatekey], privateKeyArmored: [string], publicKeyArmored: [string]} + */ + function generate_key_pair(keyType, numBits, userId, passphrase){ + var userIdPacket = new openpgp_packet_userid(); + var userIdString = userIdPacket.write_packet(userId); + + var keyPair = openpgp_crypto_generateKeyPair(keyType,numBits, passphrase, openpgp.config.config.prefer_hash_algorithm, 3); + var privKeyString = keyPair.privateKey; + var privKeyPacket = new openpgp_packet_keymaterial().read_priv_key(privKeyString.string,3,privKeyString.string.length); + if(!privKeyPacket.decryptSecretMPIs(passphrase)) + util.print_error('Issue creating key. Unable to read resulting private key'); + var privKey = new openpgp_msg_privatekey(); + privKey.privateKeyPacket = privKeyPacket; + privKey.getPreferredSignatureHashAlgorithm = function(){return openpgp.config.config.prefer_hash_algorithm};//need to override this to solve catch 22 to generate signature. 8 is value for SHA256 + + var publicKeyString = privKey.privateKeyPacket.publicKey.data; + var hashData = String.fromCharCode(0x99)+ String.fromCharCode(((publicKeyString.length) >> 8) & 0xFF) + + String.fromCharCode((publicKeyString.length) & 0xFF) +publicKeyString+String.fromCharCode(0xB4) + + String.fromCharCode((userId.length) >> 24) +String.fromCharCode(((userId.length) >> 16) & 0xFF) + + String.fromCharCode(((userId.length) >> 8) & 0xFF) + String.fromCharCode((userId.length) & 0xFF) + userId + var signature = new openpgp_packet_signature(); + signature = signature.write_message_signature(16,hashData, privKey); + var publicArmored = openpgp_encoding_armor(4, keyPair.publicKey.string + userIdString + signature.openpgp ); + + var privArmored = openpgp_encoding_armor(5,privKeyString.string+userIdString+signature.openpgp); + + return {privateKey : privKey, privateKeyArmored: privArmored, publicKeyArmored: publicArmored} + } + + this.generate_key_pair = generate_key_pair; + this.write_signed_message = write_signed_message; + this.write_signed_and_encrypted_message = write_signed_and_encrypted_message; + this.write_encrypted_message = write_encrypted_message; + this.read_message = read_message; + this.read_publicKey = read_publicKey; + this.read_privateKey = read_privateKey; + this.init = init; +} + +var openpgp = new _openpgp(); + + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc Decoded public key object for internal openpgp.js use + */ function openpgp_msg_publickey() { this.data; this.position; @@ -12693,6 +10221,277 @@ function openpgp_msg_publickey() { } // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the GPG4Browsers config object + * + * This object contains configuration values and implements + * storing and retrieving configuration them from HTML5 local storage. + * + * This object can be accessed after calling openpgp.init() + * using openpgp.config + * Stored config parameters can be accessed using + * openpgp.config.config + */ +function openpgp_config() { + this.config = null; + + /** + * the default config object which is used if no + * configuration was in place + */ + this.default_config = { + prefer_hash_algorithm: 2, + encryption_cipher: 9, + compression: 1, + show_version: true, + show_comment: true, + integrity_protect: true, + composition_behavior: 0, + keyserver: "keyserver.linux.it" // "pgp.mit.edu:11371" + }; + + this.versionstring ="OpenPGP.js v.1.20120905"; + this.commentstring ="http://openpgpjs.org"; + /** + * reads the config out of the HTML5 local storage + * and initializes the object config. + * if config is null the default config will be used + * @return [void] + */ + function read() { + var cf = JSON.parse(window.localStorage.getItem("config")); + if (cf == null) { + this.config = this.default_config; + this.write(); + } + else + this.config = cf; + } + + /** + * if enabled, debug messages will be printed + */ + this.debug = false; + + /** + * writes the config to HTML5 local storage + * @return [void] + */ + function write() { + window.localStorage.setItem("config",JSON.stringify(this.config)); + } + + this.read = read; + this.write = write; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc Class that represents a decoded private key for internal openpgp.js use + */ + +function openpgp_msg_privatekey() { + this.subKeys = new Array(); + this.privateKeyPacket = null; + this.userIds = new Array(); + this.userAttributes = new Array(); + this.revocationSignatures = new Array(); + this.subKeys = new Array(); + + /** + * + * @return last position + */ + function read_nodes(parent_node, input, position, len) { + this.privateKeyPacket = parent_node; + + var pos = position; + while (input.length > pos) { + var result = openpgp_packet.read_packet(input, pos, input.length - pos); + if (result == null) { + util.print_error("openpgp.msg.messge decrypt:\n"+'[pub/priv_key]parsing ends here @:' + pos + " l:" + len); + break; + } else { + switch (result.tagType) { + case 2: // public key revocation signature + if (result.signatureType == 32) + this.revocationSignatures[this.revocationSignatures.length] = result; + else if (result.signatureType > 15 && result.signatureType < 20) { + if (this.certificationsignatures == null) + this.certificationSignatures = new Array(); + this.certificationSignatures[this.certificationSignatures.length] = result; + } else + util.print_error("openpgp.msg.messge decrypt:\n"+"unknown signature type directly on key "+result.signatureType+" @"+pos); + pos += result.packetLength + result.headerLength; + break; + case 7: // PrivateSubkey Packet + this.subKeys[this.subKeys.length] = result; + pos += result.packetLength + result.headerLength; + pos += result.read_nodes(this.privateKeyPacket,input, pos, input.length - pos); + break; + case 17: // User Attribute Packet + this.userAttributes[this.userAttributes.length] = result; + pos += result.packetLength + result.headerLength; + pos += result.read_nodes(this.privateKeyPacket,input, pos, input.length - pos); + break; + case 13: // User ID Packet + this.userIds[this.userIds.length] = result; + pos += result.packetLength + result.headerLength; + pos += result.read_nodes(this.privateKeyPacket, input, pos, input.length - pos); + break; + default: + this.position = position - this.privateKeyPacket.packetLength - this.privateKeyPacket.headerLength; + this.len = pos - position; + return this.len; + } + } + } + this.position = position - this.privateKeyPacket.packetLength - this.privateKeyPacket.headerLength; + this.len = pos - position; + + return this.len; + } + + function getKeyId() { + return this.privateKeyPacket.publicKey.getKeyId(); + } + + + function getSubKeyIds() { + if (this.privateKeyPacket.publicKey.version == 4) // V3 keys MUST NOT have subkeys. + var result = new Array(); + for (var i = 0; i < this.subKeys.length; i++) { + result[i] = str_sha1(this.subKeys[i].publicKey.header+this.subKeys[i].publicKey.data).substring(12,20); + } + return result; + } + + + function getSigningKey() { + if ((this.privateKeyPacket.publicKey.publicKeyAlgorithm == 17 || + this.privateKeyPacket.publicKey.publicKeyAlgorithm != 2) + && this.privateKeyPacket.publicKey.verifyKey() == 3) + return this.privateKeyPacket; + else if (this.privateKeyPacket.publicKey.version == 4) // V3 keys MUST NOT have subkeys. + for (var j = 0; j < this.privateKeyPacket.subKeys.length; j++) { + if ((this.privateKeyPacket.subKeys[j].publicKey.publicKeyAlgorithm == 17 || + this.privateKeyPacket.subKeys[j].publicKey.publicKeyAlgorithm != 2) && + this.privateKeyPacket.subKeys[j].publicKey.verifyKey() == 3) + return this.privateKeyPacket.subKeys[j]; + } + return null; + } + + function getPreferredSignatureHashAlgorithm() { + var pkey = this.getSigningKey(); + if (pkey == null) { + util.print_error("private key is for encryption only! Cannot create a signature.") + return null; + } + if (pkey.publicKey.publicKeyAlgorithm == 17) { + var dsa = new DSA(); + return dsa.select_hash_algorithm(pkey.publicKey.MPIs[1].toBigInteger()); // q + } + return openpgp.config.config.prefer_hash_algorithm; + + } + + function decryptSecretMPIs(str_passphrase) { + return this.privateKeyPacket.decryptSecretMPIs(str_passphrase); + } + + function getFingerprint() { + return this.privateKeyPacket.publicKey.getFingerprint(); + } + + // TODO need to implement this + function revoke() { + + } + + /** + * extracts the public key part + * @return {String} OpenPGP armored text containing the public key + * returns null if no sufficient data to extract public key + */ + function extractPublicKey() { + // add public key + var key = this.privateKeyPacket.publicKey.header + this.privateKeyPacket.publicKey.data; + for (var i = 0; i < this.userIds.length; i++) { + // verify userids + if (this.userIds[i].certificationSignatures.length === 0) { + util.print_error("extractPublicKey - missing certification signatures"); + return null; + } + var userIdPacket = new openpgp_packet_userid(); + // add userids + key += userIdPacket.write_packet(this.userIds[i].text); + for (var j = 0; j < this.userIds[i].certificationSignatures.length; j++) { + var certSig = this.userIds[i].certificationSignatures[j]; + // add signatures + key += openpgp_packet.write_packet_header(2, certSig.data.length) + certSig.data; + } + } + for (var k = 0; k < this.subKeys.length; k++) { + var pubSubKey = this.subKeys[k].publicKey; + // add public subkey package + key += openpgp_packet.write_old_packet_header(14, pubSubKey.data.length) + pubSubKey.data; + var subKeySig = this.subKeys[k].subKeySignature; + if (subKeySig !== null) { + // add subkey signature + key += openpgp_packet.write_packet_header(2, subKeySig.data.length) + subKeySig.data; + } else { + util.print_error("extractPublicKey - missing subkey signature"); + return null; + } + } + var publicArmored = openpgp_encoding_armor(4, key); + return publicArmored; + } + + this.extractPublicKey = extractPublicKey; + this.getSigningKey = getSigningKey; + this.getFingerprint = getFingerprint; + this.getPreferredSignatureHashAlgorithm = getPreferredSignatureHashAlgorithm; + this.read_nodes = read_nodes; + this.decryptSecretMPIs = decryptSecretMPIs; + this.getSubKeyIds = getSubKeyIds; + this.getKeyId = getKeyId; + +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -13149,3 +10948,2224 @@ function createcrc24(input) { return crc & 0xffffff; } +JXG = {exists: (function(undefined){return function(v){return !(v===undefined || v===null);}})()}; +JXG.decompress = function(str) {return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip()[0][0]);}; +/* + Copyright 2008-2012 + Matthias Ehmann, + Michael Gerhaeuser, + Carsten Miller, + Bianca Valentin, + Alfred Wassermann, + Peter Wilfahrt + + This file is part of JSXGraph. + + Dual licensed under the Apache License Version 2.0, or LGPL Version 3 licenses. + + You should have received a copy of the GNU Lesser General Public License + along with JSXCompressor. If not, see . + + You should have received a copy of the Apache License along with JSXCompressor. + If not, see . + +*/ + +/** + * @fileoverview Utilities for uncompressing and base64 decoding + */ + +/** + * @class Util class + * Class for gunzipping, unzipping and base64 decoding of files. + * It is used for reading GEONExT, Geogebra and Intergeo files. + * + * Only Huffman codes are decoded in gunzip. + * The code is based on the source code for gunzip.c by Pasi Ojala + * @see http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c + * @see http://www.cs.tut.fi/~albert + */ +JXG.Util = {}; + +/** + * Unzip zip files + */ +JXG.Util.Unzip = function (barray){ + var outputArr = [], + output = "", + debug = false, + gpflags, + files = 0, + unzipped = [], + crc, + buf32k = new Array(32768), + bIdx = 0, + modeZIP=false, + + CRC, SIZE, + + bitReverse = [ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff + ], + + cplens = [ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + ], + + cplext = [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 + ], /* 99==invalid */ + + cpdist = [ + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, + 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, + 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, + 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 + ], + + cpdext = [ + 0, 0, 0, 0, 1, 1, 2, 2, + 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 13, 13 + ], + + border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15], + + bA = barray, + + bytepos=0, + bitpos=0, + bb = 1, + bits=0, + + NAMEMAX = 256, + + nameBuf = [], + + fileout; + + function readByte(){ + bits+=8; + if (bytepos"); + return bA[bytepos++]; + } else + return -1; + }; + + function byteAlign(){ + bb = 1; + }; + + function readBit(){ + var carry; + bits++; + carry = (bb & 1); + bb >>= 1; + if (bb==0){ + bb = readByte(); + carry = (bb & 1); + bb = (bb>>1) | 0x80; + } + return carry; + }; + + function readBits(a) { + var res = 0, + i = a; + + while(i--) { + res = (res<<1) | readBit(); + } + if(a) { + res = bitReverse[res]>>(8-a); + } + return res; + }; + + function flushBuffer(){ + //document.write('FLUSHBUFFER:'+buf32k); + bIdx = 0; + }; + function addBuffer(a){ + SIZE++; + //CRC=updcrc(a,crc); + buf32k[bIdx++] = a; + outputArr.push(String.fromCharCode(a)); + //output+=String.fromCharCode(a); + if(bIdx==0x8000){ + //document.write('ADDBUFFER:'+buf32k); + bIdx=0; + } + }; + + function HufNode() { + this.b0=0; + this.b1=0; + this.jump = null; + this.jumppos = -1; + }; + + var LITERALS = 288; + + var literalTree = new Array(LITERALS); + var distanceTree = new Array(32); + var treepos=0; + var Places = null; + var Places2 = null; + + var impDistanceTree = new Array(64); + var impLengthTree = new Array(64); + + var len = 0; + var fpos = new Array(17); + fpos[0]=0; + var flens; + var fmax; + + function IsPat() { + while (1) { + if (fpos[len] >= fmax) + return -1; + if (flens[fpos[len]] == len) + return fpos[len]++; + fpos[len]++; + } + }; + + function Rec() { + var curplace = Places[treepos]; + var tmp; + if (debug) + document.write("
len:"+len+" treepos:"+treepos); + if(len==17) { //war 17 + return -1; + } + treepos++; + len++; + + tmp = IsPat(); + if (debug) + document.write("
IsPat "+tmp); + if(tmp >= 0) { + curplace.b0 = tmp; /* leaf cell for 0-bit */ + if (debug) + document.write("
b0 "+curplace.b0); + } else { + /* Not a Leaf cell */ + curplace.b0 = 0x8000; + if (debug) + document.write("
b0 "+curplace.b0); + if(Rec()) + return -1; + } + tmp = IsPat(); + if(tmp >= 0) { + curplace.b1 = tmp; /* leaf cell for 1-bit */ + if (debug) + document.write("
b1 "+curplace.b1); + curplace.jump = null; /* Just for the display routine */ + } else { + /* Not a Leaf cell */ + curplace.b1 = 0x8000; + if (debug) + document.write("
b1 "+curplace.b1); + curplace.jump = Places[treepos]; + curplace.jumppos = treepos; + if(Rec()) + return -1; + } + len--; + return 0; + }; + + function CreateTree(currentTree, numval, lengths, show) { + var i; + /* Create the Huffman decode tree/table */ + //document.write("
createtree
"); + if (debug) + document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show); + Places = currentTree; + treepos=0; + flens = lengths; + fmax = numval; + for (i=0;i<17;i++) + fpos[i] = 0; + len = 0; + if(Rec()) { + //fprintf(stderr, "invalid huffman tree\n"); + if (debug) + alert("invalid huffman tree\n"); + return -1; + } + if (debug){ + document.write('
Tree: '+Places.length); + for (var a=0;a<32;a++){ + document.write("Places["+a+"].b0="+Places[a].b0+"
"); + document.write("Places["+a+"].b1="+Places[a].b1+"
"); + } + } + + /*if(show) { + var tmp; + for(tmp=currentTree;tmpjump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); + if(!(tmp.b0 & 0x8000)) { + //fprintf(stdout, " 0x%03x (%c)", tmp->b0,(tmp->b0<256 && isprint(tmp->b0))?tmp->b0:'�'); + } + if(!(tmp.b1 & 0x8000)) { + if((tmp.b0 & 0x8000)) + fprintf(stdout, " "); + fprintf(stdout, " 0x%03x (%c)", tmp->b1,(tmp->b1<256 && isprint(tmp->b1))?tmp->b1:'�'); + } + fprintf(stdout, "\n"); + } + }*/ + return 0; + }; + + function DecodeValue(currentTree) { + var len, i, + xtreepos=0, + X = currentTree[xtreepos], + b; + + /* decode one symbol of the data */ + while(1) { + b=readBit(); + if (debug) + document.write("b="+b); + if(b) { + if(!(X.b1 & 0x8000)){ + if (debug) + document.write("ret1"); + return X.b1; /* If leaf node, return data */ + } + X = X.jump; + len = currentTree.length; + for (i=0;i>1); + if(j > 23) { + j = (j<<1) | readBit(); /* 48..255 */ + + if(j > 199) { /* 200..255 */ + j -= 128; /* 72..127 */ + j = (j<<1) | readBit(); /* 144..255 << */ + } else { /* 48..199 */ + j -= 48; /* 0..151 */ + if(j > 143) { + j = j+136; /* 280..287 << */ + /* 0..143 << */ + } + } + } else { /* 0..23 */ + j += 256; /* 256..279 << */ + } + if(j < 256) { + addBuffer(j); + //document.write("out:"+String.fromCharCode(j)); + /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ + } else if(j == 256) { + /* EOF */ + break; + } else { + var len, dist; + + j -= 256 + 1; /* bytes + EOF */ + len = readBits(cplext[j]) + cplens[j]; + + j = bitReverse[readBits(5)]>>3; + if(cpdext[j] > 8) { + dist = readBits(8); + dist |= (readBits(cpdext[j]-8)<<8); + } else { + dist = readBits(cpdext[j]); + } + dist += cpdist[j]; + + /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ + for(j=0;jparam: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); + for(j=0; j<19; j++) { + ll[j] = 0; + } + + // Get the decode tree code lengths + + //document.write("
"); + for(j=0; jll:'+ll); + len = distanceTree.length; + for (i=0; idistanceTree"); + for(var a=0;a"+distanceTree[a].b0+" "+distanceTree[a].b1+" "+distanceTree[a].jump+" "+distanceTree[a].jumppos); + /*if (distanceTree[a].jumppos!=-1) + document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); + */ + } + } + //document.write('
tree created'); + + //read in literal and distance code lengths + n = literalCodes + distCodes; + i = 0; + var z=-1; + if (debug) + document.write("
n="+n+" bits: "+bits+"
"); + while(i < n) { + z++; + j = DecodeValue(distanceTree); + if (debug) + document.write("
"+z+" i:"+i+" decode: "+j+" bits "+bits+"
"); + if(j<16) { // length of code in bits (0..15) + ll[i++] = j; + } else if(j==16) { // repeat last length 3 to 6 times + var l; + j = 3 + readBits(2); + if(i+j > n) { + flushBuffer(); + return 1; + } + l = i ? ll[i-1] : 0; + while(j--) { + ll[i++] = l; + } + } else { + if(j==17) { // 3 to 10 zero length codes + j = 3 + readBits(3); + } else { // j == 18: 11 to 138 zero length codes + j = 11 + readBits(7); + } + if(i+j > n) { + flushBuffer(); + return 1; + } + while(j--) { + ll[i++] = 0; + } + } + } + /*for(j=0; jliteralTree"); + while(1) { + j = DecodeValue(literalTree); + if(j >= 256) { // In C64: if carry set + var len, dist; + j -= 256; + if(j == 0) { + // EOF + break; + } + j--; + len = readBits(cplext[j]) + cplens[j]; + + j = DecodeValue(distanceTree); + if(cpdext[j] > 8) { + dist = readBits(8); + dist |= (readBits(cpdext[j]-8)<<8); + } else { + dist = readBits(cpdext[j]); + } + dist += cpdist[j]; + while(len--) { + var c = buf32k[(bIdx - dist) & 0x7fff]; + addBuffer(c); + } + } else { + addBuffer(j); + } + } + } + } while(!last); + flushBuffer(); + + byteAlign(); + return 0; +}; + +JXG.Util.Unzip.prototype.unzipFile = function(name) { + var i; + this.unzip(); + //alert(unzipped[0][1]); + for (i=0;i"); + } + */ + //alert(bA); + nextFile(); + return unzipped; + }; + + function nextFile(){ + if (debug) + alert("NEXTFILE"); + outputArr = []; + var tmp = []; + modeZIP = false; + tmp[0] = readByte(); + tmp[1] = readByte(); + if (debug) + alert("type: "+tmp[0]+" "+tmp[1]); + if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("da",16)){ //GZIP + if (debug) + alert("GEONExT-GZIP"); + DeflateLoop(); + if (debug) + alert(outputArr.join('')); + unzipped[files] = new Array(2); + unzipped[files][0] = outputArr.join(''); + unzipped[files][1] = "geonext.gxt"; + files++; + } + if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("9c",16)){ //ZLIB + if (debug) + alert("ZLIB"); + DeflateLoop(); + if (debug) + alert(outputArr.join('')); + unzipped[files] = new Array(2); + unzipped[files][0] = outputArr.join(''); + unzipped[files][1] = "ZLIB"; + files++; + } + if (tmp[0] == parseInt("1f",16) && tmp[1] == parseInt("8b",16)){ //GZIP + if (debug) + alert("GZIP"); + //DeflateLoop(); + skipdir(); + if (debug) + alert(outputArr.join('')); + unzipped[files] = new Array(2); + unzipped[files][0] = outputArr.join(''); + unzipped[files][1] = "file"; + files++; + } + if (tmp[0] == parseInt("50",16) && tmp[1] == parseInt("4b",16)){ //ZIP + modeZIP = true; + tmp[2] = readByte(); + tmp[3] = readByte(); + if (tmp[2] == parseInt("3",16) && tmp[3] == parseInt("4",16)){ + //MODE_ZIP + tmp[0] = readByte(); + tmp[1] = readByte(); + if (debug) + alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10); + + gpflags = readByte(); + gpflags |= (readByte()<<8); + if (debug) + alert("gpflags: "+gpflags); + + var method = readByte(); + method |= (readByte()<<8); + if (debug) + alert("method: "+method); + + readByte(); + readByte(); + readByte(); + readByte(); + + var crc = readByte(); + crc |= (readByte()<<8); + crc |= (readByte()<<16); + crc |= (readByte()<<24); + + var compSize = readByte(); + compSize |= (readByte()<<8); + compSize |= (readByte()<<16); + compSize |= (readByte()<<24); + + var size = readByte(); + size |= (readByte()<<8); + size |= (readByte()<<16); + size |= (readByte()<<24); + + if (debug) + alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize); + + var filelen = readByte(); + filelen |= (readByte()<<8); + + var extralen = readByte(); + extralen |= (readByte()<<8); + + if (debug) + alert("filelen "+filelen); + i = 0; + nameBuf = []; + while (filelen--){ + var c = readByte(); + if (c == "/" | c ==":"){ + i = 0; + } else if (i < NAMEMAX-1) + nameBuf[i++] = String.fromCharCode(c); + } + if (debug) + alert("nameBuf: "+nameBuf); + + //nameBuf[i] = "\0"; + if (!fileout) + fileout = nameBuf; + + var i = 0; + while (i < extralen){ + c = readByte(); + i++; + } + + CRC = 0xffffffff; + SIZE = 0; + + if (size = 0 && fileOut.charAt(fileout.length-1)=="/"){ + //skipdir + if (debug) + alert("skipdir"); + } + if (method == 8){ + DeflateLoop(); + if (debug) + alert(outputArr.join('')); + unzipped[files] = new Array(2); + unzipped[files][0] = outputArr.join(''); + unzipped[files][1] = nameBuf.join(''); + files++; + //return outputArr.join(''); + } + skipdir(); + } + } + }; + +function skipdir(){ + var crc, + tmp = [], + compSize, size, os, i, c; + + if ((gpflags & 8)) { + tmp[0] = readByte(); + tmp[1] = readByte(); + tmp[2] = readByte(); + tmp[3] = readByte(); + + if (tmp[0] == parseInt("50",16) && + tmp[1] == parseInt("4b",16) && + tmp[2] == parseInt("07",16) && + tmp[3] == parseInt("08",16)) + { + crc = readByte(); + crc |= (readByte()<<8); + crc |= (readByte()<<16); + crc |= (readByte()<<24); + } else { + crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24); + } + + compSize = readByte(); + compSize |= (readByte()<<8); + compSize |= (readByte()<<16); + compSize |= (readByte()<<24); + + size = readByte(); + size |= (readByte()<<8); + size |= (readByte()<<16); + size |= (readByte()<<24); + + if (debug) + alert("CRC:"); + } + + if (modeZIP) + nextFile(); + + tmp[0] = readByte(); + if (tmp[0] != 8) { + if (debug) + alert("Unknown compression method!"); + return 0; + } + + gpflags = readByte(); + if (debug){ + if ((gpflags & ~(parseInt("1f",16)))) + alert("Unknown flags set!"); + } + + readByte(); + readByte(); + readByte(); + readByte(); + + readByte(); + os = readByte(); + + if ((gpflags & 4)){ + tmp[0] = readByte(); + tmp[2] = readByte(); + len = tmp[0] + 256*tmp[1]; + if (debug) + alert("Extra field size: "+len); + for (i=0;ihttp://www.webtoolkit.info/ +*/ +JXG.Util.Base64 = { + + // private property + _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + + // public method for encoding + encode : function (input) { + var output = [], + chr1, chr2, chr3, enc1, enc2, enc3, enc4, + i = 0; + + input = JXG.Util.Base64._utf8_encode(input); + + while (i < input.length) { + + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output.push([this._keyStr.charAt(enc1), + this._keyStr.charAt(enc2), + this._keyStr.charAt(enc3), + this._keyStr.charAt(enc4)].join('')); + } + + return output.join(''); + }, + + // public method for decoding + decode : function (input, utf8) { + var output = [], + chr1, chr2, chr3, + enc1, enc2, enc3, enc4, + i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output.push(String.fromCharCode(chr1)); + + if (enc3 != 64) { + output.push(String.fromCharCode(chr2)); + } + if (enc4 != 64) { + output.push(String.fromCharCode(chr3)); + } + } + + output = output.join(''); + + if (utf8) { + output = JXG.Util.Base64._utf8_decode(output); + } + return output; + + }, + + // private method for UTF-8 encoding + _utf8_encode : function (string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode : function (utftext) { + var string = [], + i = 0, + c = 0, c2 = 0, c3 = 0; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + if (c < 128) { + string.push(String.fromCharCode(c)); + i++; + } + else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + i += 2; + } + else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + i += 3; + } + } + return string.join(''); + }, + + _destrip: function (stripped, wrap){ + var lines = [], lineno, i, + destripped = []; + + if (wrap==null) + wrap = 76; + + stripped.replace(/ /g, ""); + lineno = stripped.length / wrap; + for (i = 0; i < lineno; i++) + lines[i]=stripped.substr(i * wrap, wrap); + if (lineno != stripped.length / wrap) + lines[lines.length]=stripped.substr(lineno * wrap, stripped.length-(lineno * wrap)); + + for (i = 0; i < lines.length; i++) + destripped.push(lines[i]); + return destripped.join('\n'); + }, + + decodeAsArray: function (input){ + var dec = this.decode(input), + ar = [], i; + for (i=0;i255){ + switch (c) { + case 8364: c=128; + break; + case 8218: c=130; + break; + case 402: c=131; + break; + case 8222: c=132; + break; + case 8230: c=133; + break; + case 8224: c=134; + break; + case 8225: c=135; + break; + case 710: c=136; + break; + case 8240: c=137; + break; + case 352: c=138; + break; + case 8249: c=139; + break; + case 338: c=140; + break; + case 381: c=142; + break; + case 8216: c=145; + break; + case 8217: c=146; + break; + case 8220: c=147; + break; + case 8221: c=148; + break; + case 8226: c=149; + break; + case 8211: c=150; + break; + case 8212: c=151; + break; + case 732: c=152; + break; + case 8482: c=153; + break; + case 353: c=154; + break; + case 8250: c=155; + break; + case 339: c=156; + break; + case 382: c=158; + break; + case 376: c=159; + break; + default: + break; + } + } + return c; +}; + +/** + * Decoding string into utf-8 + * @param {String} string to decode + * @return {String} utf8 decoded string + */ +JXG.Util.utf8Decode = function(utftext) { + var string = []; + var i = 0; + var c = 0, c1 = 0, c2 = 0, c3; + if (!JXG.exists(utftext)) return ''; + + while ( i < utftext.length ) { + c = utftext.charCodeAt(i); + + if (c < 128) { + string.push(String.fromCharCode(c)); + i++; + } else if((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i+1); + string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + i += 2; + } else { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + i += 3; + } + }; + return string.join(''); +}; + +/** + * Generate a random uuid. + * http://www.broofa.com + * mailto:robert@broofa.com + * + * Copyright (c) 2010 Robert Kieffer + * Dual licensed under the MIT and GPL licenses. + * + * EXAMPLES: + * >>> Math.uuid() + * "92329D39-6F5C-4520-ABFC-AAB64544E172" + */ +JXG.Util.genUUID = function() { + // Private array of chars to use + var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), + uuid = new Array(36), rnd=0, r; + + for (var i = 0; i < 36; i++) { + if (i==8 || i==13 || i==18 || i==23) { + uuid[i] = '-'; + } else if (i==14) { + uuid[i] = '4'; + } else { + if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; + r = rnd & 0xf; + rnd = rnd >> 4; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + } + } + + return uuid.join(''); +}; + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @protected + * @class + * @classdesc Top-level message object. Contains information from one or more packets + */ + +function openpgp_msg_message() { + + // -1 = no valid passphrase submitted + // -2 = no private key found + // -3 = decryption error + // text = valid decryption + this.text = ""; + + /** + * Decrypts a message and generates user interface message out of the found. + * MDC will be verified as well as message signatures + * @param {openpgp_msg_privatekey} private_key the private the message is encrypted with (corresponding to the session key) + * @param {openpgp_packet_encryptedsessionkey} sessionkey the session key to be used to decrypt the message + * @return {String} plaintext of the message or null on error + */ + function decrypt(private_key, sessionkey) { + return this.decryptAndVerifySignature(private_key, sessionkey).text; + } + + /** + * Decrypts a message and generates user interface message out of the found. + * MDC will be verified as well as message signatures + * @param {openpgp_msg_privatekey} private_key the private the message is encrypted with (corresponding to the session key) + * @param {openpgp_packet_encryptedsessionkey} sessionkey the session key to be used to decrypt the message + * @param {openpgp_msg_publickey} pubkey Array of public keys to check signature against. If not provided, checks local keystore. + * @return {String} plaintext of the message or null on error + */ + function decryptAndVerifySignature(private_key, sessionkey, pubkey) { + if (private_key == null || sessionkey == null || sessionkey == "") + return null; + var decrypted = sessionkey.decrypt(this, private_key.keymaterial); + if (decrypted == null) + return null; + var packet; + var position = 0; + var len = decrypted.length; + var validSignatures = new Array(); + util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",decrypted); + + while (position != decrypted.length && (packet = openpgp_packet.read_packet(decrypted, position, len)) != null) { + if (packet.tagType == 8) { + this.text = packet.decompress(); + decrypted = packet.decompress(); + } + util.print_debug(packet.toString()); + position += packet.headerLength+packet.packetLength; + if (position > 38) + util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",decrypted.substring(position)); + len = decrypted.length - position; + if (packet.tagType == 11) { + this.text = packet.data; + util.print_info("message successfully decrypted"); + } + if (packet.tagType == 19) + // ignore.. we checked that already in a more strict way. + continue; + if (packet.tagType == 2 && packet.signatureType < 3) { + if(!pubkey || pubkey.length == 0 ){ + var pubkey = openpgp.keyring.getPublicKeysForKeyId(packet.issuerKeyId); + } + if (pubkey.length == 0) { + util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(packet.issuerKeyId)+". Public key not found in keyring."); + validSignatures[validSignatures.length] = false; + } else { + if(packet.verify(this.text.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"),pubkey[0]) && pubkey[0].obj.validate()){ + util.print_info("Found Good Signature from "+pubkey[0].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); + validSignatures[validSignatures.length] = true; + } + else{ + util.print_error("Signature verification failed: Bad Signature from "+pubkey[0].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); + validSignatures[validSignatures.length] = false; + } + } + } + } + if (this.text == "") { + this.text = decrypted; + } + return {text:this.text, validSignatures:validSignatures}; + } + + /** + * Verifies a message signature. This function can be called after read_message if the message was signed only. + * @param {openpgp_msg_publickey} pubkey Array of public keys to check signature against. If not provided, checks local keystore. + * @return {boolean} true if the signature was correct; otherwise false + */ + function verifySignature(pubkey) { + var result = false; + if (this.type == 2) { + if(!pubkey || pubkey.length == 0){ + var pubkey; + if (this.signature.version == 4) { + pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.issuerKeyId); + } else if (this.signature.version == 3) { + pubkey = openpgp.keyring.getPublicKeysForKeyId(this.signature.keyId); + } else { + util.print_error("unknown signature type on message!"); + return false; + } + } + if (pubkey.length == 0) + util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(this.signature.issuerKeyId)+". Public key not found in keyring."); + else { + for (var i = 0 ; i < pubkey.length; i++) { + var tohash = this.text.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"); + if (this.signature.verify(tohash.substring(0, tohash.length -2), pubkey[i])) { + util.print_info("Found Good Signature from "+pubkey[i].obj.userIds[i].text+" (0x"+util.hexstrdump(pubkey[i].obj.getKeyId()).substring(8)+")"); + result = true; + } else { + util.print_error("Signature verification failed: Bad Signature from "+pubkey[i].obj.userIds[0].text+" (0x"+util.hexstrdump(pubkey[0].obj.getKeyId()).substring(8)+")"); + } + } + } + } + return result; + } + + function toString() { + var result = "Session Keys:\n"; + if (this.sessionKeys !=null) + for (var i = 0; i < this.sessionKeys.length; i++) { + result += this.sessionKeys[i].toString(); + } + result += "\n\n EncryptedData:\n"; + if(this.encryptedData != null) + result += this.encryptedData.toString(); + + result += "\n\n Signature:\n"; + if(this.signature != null) + result += this.signature.toString(); + + result += "\n\n Text:\n" + if(this.signature != null) + result += this.text; + return result; + } + this.decrypt = decrypt; + this.decryptAndVerifySignature = decryptAndVerifySignature; + this.verifySignature = verifySignature; + this.toString = toString; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// Hint: We hold our MPIs as an array of octets in big endian format preceeding a two +// octet scalar: MPI: [a,b,c,d,e,f] +// - MPI size: (a << 8) | b +// - MPI = c | d << 8 | e << ((MPI.length -2)*8) | f ((MPI.length -2)*8) + +/** + * Implementation of type MPI (RFC4880 3.2) + * Multiprecision integers (also called MPIs) are unsigned integers used + * to hold large integers such as the ones used in cryptographic + * calculations. + * An MPI consists of two pieces: a two-octet scalar that is the length + * of the MPI in bits followed by a string of octets that contain the + * actual integer. + */ +function openpgp_type_mpi() { + this.MPI = null; + this.mpiBitLength = null; + this.mpiByteLength = null; + this.data = null; + /** + * parsing function for a mpi (RFC 4880 3.2). + * @param input [string] payload of mpi data + * @param position [integer] position to start reading from the input string + * @param len [integer] length of the packet or the remaining length of input at position + * @return [openpgp_type_mpi] object representation + */ + function read(input, position, len) { + var mypos = position; + + this.mpiBitLength = (input[mypos++].charCodeAt() << 8) | input[mypos++].charCodeAt(); + + // Additional rules: + // + // The size of an MPI is ((MPI.length + 7) / 8) + 2 octets. + // + // The length field of an MPI describes the length starting from its + // most significant non-zero bit. Thus, the MPI [00 02 01] is not + // formed correctly. It should be [00 01 01]. + + // TODO: Verification of this size method! This size calculation as + // specified above is not applicable in JavaScript + this.mpiByteLength = (this.mpiBitLength - (this.mpiBitLength % 8)) / 8; + if (this.mpiBitLength % 8 != 0) + this.mpiByteLength++; + + this.MPI = input.substring(mypos,mypos+this.mpiByteLength); + this.data = input.substring(position, position+2+this.mpiByteLength); + this.packetLength = this.mpiByteLength +2; + return this; + } + + /** + * generates debug output (pretty print) + * @return String which gives some information about the mpi + */ + function toString() { + var r = " MPI("+this.mpiBitLength+"b/"+this.mpiByteLength+"B) : 0x"; + r+=util.hexstrdump(this.MPI); + return r+'\n'; + } + + /** + * converts the mpi to an BigInteger object + * @return [BigInteger] + */ + function getBigInteger() { + return new BigInteger(util.hexstrdump(this.MPI),16); + } + + + function getBits(num) { + for (var i = 0; i < 9; i++) + if (num >> i == 0) + return i; + } + + /** + * gets the length of the mpi in bytes + * @return [integer] mpi byte length + */ + function getByteLength() { + return this.mpiByteLength; + } + + /** + * creates an mpi from the specified string + * @param data [String] data to read the mpi from + * @return [openpgp_type_mpi] + */ + function create(data) { + this.MPI = data; + this.mpiBitLength = (data.length -1) *8 + getBits(data.charCodeAt(0)); + this.mpiByteLength = data.length; + return this; + } + + /** + * converts the mpi object to a string as specified in RFC4880 3.2 + * @return [String] mpi byte representation + */ + function toBin() { + var result = String.fromCharCode((this.mpiBitLength >> 8) & 0xFF); + result += String.fromCharCode(this.mpiBitLength & 0xFF); + result += this.MPI; + return result; + } + + this.read = read; + this.toBigInteger = getBigInteger; + this.toString = toString; + this.create = create; + this.toBin = toBin; + this.getByteLength = getByteLength; +} + +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of type key id (RFC4880 3.3) + * A Key ID is an eight-octet scalar that identifies a key. + Implementations SHOULD NOT assume that Key IDs are unique. The + section "Enhanced Key Formats" below describes how Key IDs are + formed. + */ +function openpgp_type_keyid() { + /** + * parsing method for a key id + * @param input [String] input to read the key id from + * @param position [integer] position where to start reading the key id from input + * @return this object + */ + function read_packet(input, position) { + this.bytes = input.substring(position, position+8); + return this; + } + + /** + * generates debug output (pretty print) + * @return [String] Key Id as hexadecimal string + */ + function toString() { + return util.hexstrdump(this.bytes); + } + + this.read_packet = read_packet; + this.toString = toString; +}; +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * Implementation of the String-to-key specifier (RFC4880 3.7) + * String-to-key (S2K) specifiers are used to convert passphrase strings + into symmetric-key encryption/decryption keys. They are used in two + places, currently: to encrypt the secret part of private keys in the + private keyring, and to convert passphrases to encryption keys for + symmetrically encrypted messages. + */ +function openpgp_type_s2k() { + /** + * parsing function for a string-to-key specifier (RFC 4880 3.7). + * @param input [string] payload of string-to-key specifier + * @param position [integer] position to start reading from the input string + * @return [openpgp_type_s2k] object representation + */ + function read(input, position) { + var mypos = position; + this.type = input[mypos++].charCodeAt(); + switch (this.type) { + case 0: // Simple S2K + // Octet 1: hash algorithm + this.hashAlgorithm = input[mypos++].charCodeAt(); + this.s2kLength = 1; + break; + + case 1: // Salted S2K + // Octet 1: hash algorithm + this.hashAlgorithm = input[mypos++].charCodeAt(); + + // Octets 2-9: 8-octet salt value + this.saltValue = input.substring(mypos, mypos+8); + mypos += 8; + this.s2kLength = 9; + break; + + case 3: // Iterated and Salted S2K + // Octet 1: hash algorithm + this.hashAlgorithm = input[mypos++].charCodeAt(); + + // Octets 2-9: 8-octet salt value + this.saltValue = input.substring(mypos, mypos+8); + mypos += 8; + + // Octet 10: count, a one-octet, coded value + this.EXPBIAS = 6; + var c = input[mypos++].charCodeAt(); + this.count = (16 + (c & 15)) << ((c >> 4) + this.EXPBIAS); + this.s2kLength = 10; + break; + + case 2: // Reserved value + default: + util.print_error("unknown s2k type! "+this.type); + break; + } + return this; + } + + + /** + * writes an s2k hash based on the inputs. + * @return [String] produced key of hashAlgorithm hash length + */ + function write(type, hash, passphrase, salt, c){ + this.type = type; + if(this.type == 3){this.saltValue = salt; + this.hashAlgorithm = hash; + this.count = (16 + (c & 15)) << ((c >> 4) + 6); + this.s2kLength = 10; + } + return this.produce_key(passphrase); + } + + /** + * produces a key using the specified passphrase and the defined hashAlgorithm + * @param passphrase [String] passphrase containing user input + * @return [String] produced key with a length corresponding to hashAlgorithm hash length + */ + function produce_key(passphrase, numBytes) { + if (this.type == 0) { + return openpgp_crypto_hashData(this.hashAlgorithm,passphrase); + } else if (this.type == 1) { + return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+passphrase); + } else if (this.type == 3) { + var isp = []; + isp[0] = this.saltValue+passphrase; + while (isp.length*(this.saltValue+passphrase).length < this.count) + isp.push(this.saltValue+passphrase); + isp = isp.join(''); + if (isp.length > this.count) + isp = isp.substr(0, this.count); + if(numBytes && (numBytes == 24 || numBytes == 32)){ //This if accounts for RFC 4880 3.7.1.1 -- If hash size is greater than block size, use leftmost bits. If blocksize larger than hash size, we need to rehash isp and prepend with 0. + var key = openpgp_crypto_hashData(this.hashAlgorithm,isp); + return key + openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+isp); + } + return openpgp_crypto_hashData(this.hashAlgorithm,isp); + } else return null; + } + + this.read = read; + this.write = write; + this.produce_key = produce_key; +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + */ +function openpgp_keyring() { + + /** + * Initialization routine for the keyring. This method reads the + * keyring from HTML5 local storage and initializes this instance. + * This method is called by openpgp.init(). + * @return {null} undefined + */ + function init() { + var sprivatekeys = JSON.parse(window.localStorage.getItem("privatekeys")); + var spublickeys = JSON.parse(window.localStorage.getItem("publickeys")); + if (sprivatekeys == null || sprivatekeys.length == 0) { + sprivatekeys = new Array(); + } + + if (spublickeys == null || spublickeys.length == 0) { + spublickeys = new Array(); + } + this.publicKeys = new Array(); + this.privateKeys = new Array(); + var k = 0; + for (var i =0; i < sprivatekeys.length; i++) { + var r = openpgp.read_privateKey(sprivatekeys[i]); + this.privateKeys[k] = { armored: sprivatekeys[i], obj: r[0], keyId: r[0].getKeyId()}; + k++; + } + k = 0; + for (var i =0; i < spublickeys.length; i++) { + var r = openpgp.read_publicKey(spublickeys[i]); + if (r[0] != null) { + this.publicKeys[k] = { armored: spublickeys[i], obj: r[0], keyId: r[0].getKeyId()}; + k++; + } + } + } + this.init = init; + + /** + * Checks if at least one private key is in the keyring + * @return {boolean} True if there are private keys, else false. + */ + function hasPrivateKey() { + return this.privateKeys.length > 0; + } + this.hasPrivateKey = hasPrivateKey; + + /** + * Saves the current state of the keyring to HTML5 local storage. + * The privateKeys array and publicKeys array gets Stringified using JSON + * @return {null} undefined + */ + function store() { + var priv = new Array(); + for (var i = 0; i < this.privateKeys.length; i++) { + priv[i] = this.privateKeys[i].armored; + } + var pub = new Array(); + for (var i = 0; i < this.publicKeys.length; i++) { + pub[i] = this.publicKeys[i].armored; + } + window.localStorage.setItem("privatekeys",JSON.stringify(priv)); + window.localStorage.setItem("publickeys",JSON.stringify(pub)); + } + this.store = store; + /** + * searches all public keys in the keyring matching the address or address part of the user ids + * @param email_address + * @return {array[openpgp_msg_publickey]} the public keys associated with provided email address. + */ + function getPublicKeyForAddress(email_address) { + var results = new Array(); + var spl = email_address.split("<"); + var email = ""; + if (spl.length > 1) { + email = spl[1].split(">")[0]; + } else { + email = email_address.trim(); + } + email = email.toLowerCase(); + if(!util.emailRegEx.test(email)){ + return results; + } + for (var i =0; i < this.publicKeys.length; i++) { + for (var j = 0; j < this.publicKeys[i].obj.userIds.length; j++) { + if (this.publicKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0) + results[results.length] = this.publicKeys[i]; + } + } + return results; + } + this.getPublicKeyForAddress = getPublicKeyForAddress; + + /** + * Searches the keyring for a private key containing the specified email address + * @param {String} email_address email address to search for + * @return {Array[openpgp_msg_privatekey} private keys found + */ + function getPrivateKeyForAddress(email_address) { + var results = new Array(); + var spl = email_address.split("<"); + var email = ""; + if (spl.length > 1) { + email = spl[1].split(">")[0]; + } else { + email = email_address.trim(); + } + email = email.toLowerCase(); + if(!util.emailRegEx.test(email)){ + return results; + } + for (var i =0; i < this.privateKeys.length; i++) { + for (var j = 0; j < this.privateKeys[i].obj.userIds.length; j++) { + if (this.privateKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0) + results[results.length] = this.privateKeys[i]; + } + } + return results; + } + + this.getPrivateKeyForAddress = getPrivateKeyForAddress; + /** + * Searches the keyring for public keys having the specified key id + * @param keyId provided as string of hex number (lowercase) + * @return {Array[openpgp_msg_privatekey]} public keys found + */ + function getPublicKeysForKeyId(keyId) { + var result = new Array(); + for (var i=0; i < this.publicKeys.length; i++) + if (keyId == this.publicKeys[i].obj.getKeyId()) + result[result.length] = this.publicKeys[i]; + return result; + } + this.getPublicKeysForKeyId = getPublicKeysForKeyId; + + /** + * Searches the keyring for private keys having the specified key id + * @param {String} keyId 8 bytes as string containing the key id to look for + * @return {Array[openpgp_msg_privatekey]} private keys found + */ + function getPrivateKeyForKeyId(keyId) { + var result = new Array(); + for (var i=0; i < this.privateKeys.length; i++) { + if (keyId == this.privateKeys[i].obj.getKeyId()) { + result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.privateKeyPacket}; + } + if (this.privateKeys[i].obj.subKeys != null) { + var subkeyids = this.privateKeys[i].obj.getSubKeyIds(); + for (var j=0; j < subkeyids.length; j++) + if (keyId == util.hexstrdump(subkeyids[j])) { + result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.subKeys[j]}; + } + } + } + return result; + } + this.getPrivateKeyForKeyId = getPrivateKeyForKeyId; + + /** + * Imports a public key from an exported ascii armored message + * @param {String} armored_text PUBLIC KEY BLOCK message to read the public key from + * @return {null} nothing + */ + function importPublicKey (armored_text) { + var result = openpgp.read_publicKey(armored_text); + for (var i = 0; i < result.length; i++) { + this.publicKeys[this.publicKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()}; + } + return true; + } + + /** + * Imports a private key from an exported ascii armored message + * @param {String} armored_text PRIVATE KEY BLOCK message to read the private key from + * @return {null} nothing + */ + function importPrivateKey (armored_text, password) { + var result = openpgp.read_privateKey(armored_text); + if(!result[0].decryptSecretMPIs(password)) + return false; + for (var i = 0; i < result.length; i++) { + this.privateKeys[this.privateKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()}; + } + return true; + } + + this.importPublicKey = importPublicKey; + this.importPrivateKey = importPrivateKey; + + /** + * returns the openpgp_msg_privatekey representation of the public key at public key ring index + * @param {Integer} index the index of the public key within the publicKeys array + * @return {openpgp_msg_privatekey} the public key object + */ + function exportPublicKey(index) { + return this.publicKey[index]; + } + this.exportPublicKey = exportPublicKey; + + + /** + * Removes a public key from the public key keyring at the specified index + * @param {Integer} index the index of the public key within the publicKeys array + * @return {openpgp_msg_privatekey} The public key object which has been removed + */ + function removePublicKey(index) { + var removed = this.publicKeys.splice(index,1); + this.store(); + return removed; + } + this.removePublicKey = removePublicKey; + + /** + * returns the openpgp_msg_privatekey representation of the private key at private key ring index + * @param {Integer} index the index of the private key within the privateKeys array + * @return {openpgp_msg_privatekey} the private key object + */ + function exportPrivateKey(index) { + return this.privateKeys[index]; + } + this.exportPrivateKey = exportPrivateKey; + + /** + * Removes a private key from the private key keyring at the specified index + * @param {Integer} index the index of the private key within the privateKeys array + * @return {openpgp_msg_privatekey} The private key object which has been removed + */ + function removePrivateKey(index) { + var removed = this.privateKeys.splice(index,1); + this.store(); + return removed; + } + this.removePrivateKey = removePrivateKey; + +} +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var Util = function() { + + this.emailRegEx = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; + + this.hexdump = function(str) { + var r=[]; + var e=str.length; + var c=0; + var h; + var i = 0; + while(c' + * @param str [String] string of the debug message + * @return [String] an HTML tt entity containing a paragraph with a style attribute where the debug message is HTMLencoded in. + */ + this.print_debug = function(str) { + if (openpgp.config.debug) { + str = openpgp_encoding_html_encode(str); + showMessages("

"+str.replace(/\n/g,"
")+"

"); + } + }; + + /** + * Helper function to print a debug message. Debug + * messages are only printed if + * openpgp.config.debug is set to true. The calling + * Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
' + * Different than print_debug because will call hexstrdump iff necessary. + * @param str [String] string of the debug message + * @return [String] an HTML tt entity containing a paragraph with a style attribute where the debug message is HTMLencoded in. + */ + this.print_debug_hexstr_dump = function(str,strToHex) { + if (openpgp.config.debug) { + str = str + this.hexstrdump(strToHex); + str = openpgp_encoding_html_encode(str); + showMessages("

"+str.replace(/\n/g,"
")+"

"); + } + }; + + /** + * Helper function to print an error message. + * The calling Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
' + * @param str [String] string of the error message + * @return [String] a HTML paragraph entity with a style attribute containing the HTML encoded error message + */ + this.print_error = function(str) { + str = openpgp_encoding_html_encode(str); + showMessages("

ERROR: "+str.replace(/\n/g,"
")+"

"); + }; + + /** + * Helper function to print an info message. + * The calling Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
'. + * @param str [String] string of the info message + * @return [String] a HTML paragraph entity with a style attribute containing the HTML encoded info message + */ + this.print_info = function(str) { + str = openpgp_encoding_html_encode(str); + showMessages("

INFO: "+str.replace(/\n/g,"
")+"

"); + }; + + this.print_warning = function(str) { + str = openpgp_encoding_html_encode(str); + showMessages("

WARNING: "+str.replace(/\n/g,"
")+"

"); + }; + + this.getLeftNBits = function (string, bitcount) { + var rest = bitcount % 8; + if (rest == 0) + return string.substring(0, bitcount / 8); + var bytes = (bitcount - rest) / 8 +1; + var result = string.substring(0, bytes); + return this.shiftRight(result, 8-rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); + }; + /** + * Shifting a string to n bits right + * @param value [String] the string to shift + * @param bitcount [Integer] amount of bits to shift (MUST be smaller than 9) + * @return [String] resulting string. + */ + this.shiftRight = function(value, bitcount) { + var temp = util.str2bin(value); + if (bitcount % 8 != 0) { + for (var i = temp.length-1; i >= 0; i--) { + temp[i] >>= bitcount % 8; + if (i > 0) + temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; + } + } else { + return value; + } + return util.bin2str(temp); + }; + + /** + * Return the algorithm type as string + * @return [String] String representing the message type + */ + this.get_hashAlgorithmString = function(algo) { + switch(algo) { + case 1: + return "MD5"; + case 2: + return "SHA1"; + case 3: + return "RIPEMD160"; + case 8: + return "SHA256"; + case 9: + return "SHA384"; + case 10: + return "SHA512"; + case 11: + return "SHA224"; + } + return "unknown"; + }; +}; + +/** + * an instance that should be used. + */ +var util = new Util(); diff --git a/resources/openpgp.min.js b/resources/openpgp.min.js index 16feb8c6..4021888a 100644 --- a/resources/openpgp.min.js +++ b/resources/openpgp.min.js @@ -1,273 +1,206 @@ -function _openpgp(){this.tostring="";this.generate_key_pair=function(a,b,c,d){var e=(new openpgp_packet_userid).write_packet(c),b=openpgp_crypto_generateKeyPair(a,b,d,openpgp.config.config.prefer_hash_algorithm,3),a=b.privateKey,f=(new openpgp_packet_keymaterial).read_priv_key(a.string,3,a.string.length);f.decryptSecretMPIs(d)||util.print_error("Issue creating key. Unable to read resulting private key");d=new openpgp_msg_privatekey;d.privateKeyPacket=f;d.getPreferredSignatureHashAlgorithm=function(){return openpgp.config.config.prefer_hash_algorithm}; -f=d.privateKeyPacket.publicKey.data;f=String.fromCharCode(153)+String.fromCharCode(f.length>>8&255)+String.fromCharCode(f.length&255)+f+String.fromCharCode(180)+String.fromCharCode(c.length>>24)+String.fromCharCode(c.length>>16&255)+String.fromCharCode(c.length>>8&255)+String.fromCharCode(c.length&255)+c;c=new openpgp_packet_signature;c=c.write_message_signature(16,f,d);b=openpgp_encoding_armor(4,b.publicKey.string+e+c.openpgp);e=openpgp_encoding_armor(5,a.string+e+c.openpgp);return{privateKey:d, -privateKeyArmored:e,publicKeyArmored:b}};this.write_signed_message=function(a,b){var c=(new openpgp_packet_signature).write_message_signature(1,b.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),a),c={text:b.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),openpgp:c.openpgp,hash:c.hash};return openpgp_encoding_armor(2,c,null,null)};this.write_signed_and_encrypted_message=function(a,b,c){var d="",e=(new openpgp_packet_literaldata).write_packet(c.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"));util.print_debug_hexstr_dump("literal_packet: |"+ -e+"|\n",e);for(var f=0;fg.signatureType||3==g.tagType||8==g.tagType||9==g.tagType||10==g.tagType||11==g.tagType||18==g.tagType||19==g.tagType)if(d[d.length]=new openpgp_msg_message,d[e].messagePacket=g,d[e].type=b.type,9==g.tagType||1==g.tagType||3==g.tagType||18==g.tagType)if(9==g.tagType){util.print_error("unexpected openpgp packet");break}else if(1==g.tagType){util.print_debug("session key found:\n "+ -g.toString());var k=!0;d[e].sessionKeys=[];for(var j=0;k;)d[e].sessionKeys[j]=g,f+=g.packetLength+g.headerLength,h-=g.packetLength+g.headerLength,g=openpgp_packet.read_packet(a,f,h),1!=g.tagType&&3!=g.tagType&&(k=!1),j++;18==g.tagType||9==g.tagType?(util.print_debug("encrypted data found:\n "+g.toString()),d[e].encryptedData=g,f+=g.packetLength+g.headerLength,h-=g.packetLength+g.headerLength,e++):util.print_debug("something is wrong: "+g.tagType)}else{if(18==g.tagType){util.print_debug("symmetric encrypted data"); -break}}else if(2==g.tagType&&3>g.signatureType){d[e].text=b.text;d[e].signature=g;break}else if(8==g.tagType){util.print_error("A directly compressed message is currently not supported");break}else if(10==g.tagType)d.length=0,f+=g.packetLength+g.headerLength,h-=g.packetLength+g.headerLength;else{if(11==g.tagType){util.print_error("A direct literal message is currently not supported.");break}}else return util.print_error("no message found!"),null}return d};this.read_publicKey=function(a){for(var b= -0,c=[],d=0,a=openpgp_encoding_deArmor(a.replace(/\r/g,"")).openpgp,e=a.length;b!=a.length;){var f=openpgp_packet.read_packet(a,b,e);if(153==a[b].charCodeAt()||6==f.tagType)c[d]=new openpgp_msg_publickey,c[d].header=a.substring(b,b+3),153==a[b].charCodeAt()?(b++,e=a[b++].charCodeAt()<<8|a[b++].charCodeAt(),c[d].publicKeyPacket=new openpgp_packet_keymaterial,c[d].publicKeyPacket.header=c[d].header,c[d].publicKeyPacket.read_tag6(a,b,e),b+=c[d].publicKeyPacket.packetLength,b+=c[d].read_nodes(c[d].publicKeyPacket, -a,b,a.length-b)):(c[d]=new openpgp_msg_publickey,c[d].publicKeyPacket=f,b+=f.headerLength+f.packetLength,b+=c[d].read_nodes(f,a,b,a.length-b));else return util.print_error("no public key found!"),null;c[d].data=a.substring(0,b);d++}return c};this.read_privateKey=function(a){for(var b=[],c=0,d=0,a=openpgp_encoding_deArmor(a.replace(/\r/g,"")).openpgp,e=a.length;d!=a.length;){var f=openpgp_packet.read_packet(a,d,e);if(5==f.tagType)b[b.length]=new openpgp_msg_privatekey,d+=f.headerLength+f.packetLength, -d+=b[c].read_nodes(f,a,d,e);else return util.print_error("no block packet found!"),null;b[c].data=a.substring(0,d);c++}return b};this.init=function(){this.config=new openpgp_config;this.config.read();this.keyring=new openpgp_keyring;this.keyring.init()}}var openpgp=new _openpgp; -function openpgp_packet_encryptedsessionkey(){this.read_pub_key_packet=function(a,b,c){this.tagType=1;this.packetLength=c;var d=b;if(10>c)return util.print_error("openpgp.packet.encryptedsessionkey.js\ninvalid length"),null;this.version=a[d++].charCodeAt();this.keyId=new openpgp_type_keyid;this.keyId.read_packet(a,d);d+=8;this.publicKeyAlgorithmUsed=a[d++].charCodeAt();switch(this.publicKeyAlgorithmUsed){case 1:case 2:this.MPIs=[];this.MPIs[0]=new openpgp_type_mpi;this.MPIs[0].read(a,d,d-b);break; -case 16:this.MPIs=[];this.MPIs[0]=new openpgp_type_mpi;this.MPIs[0].read(a,d,d-b);d+=this.MPIs[0].packetLength;this.MPIs[1]=new openpgp_type_mpi;this.MPIs[1].read(a,d,d-b);break;default:util.print_error("openpgp.packet.encryptedsessionkey.js\nunknown public key packet algorithm type "+this.publicKeyAlgorithmType)}return this};this.read_symmetric_key_packet=function(a,b,c){this.tagType=3;var d=b;this.version=a[d++];this.symmetricKeyAlgorithmUsed=a[d++];this.s2k=new openpgp_type_s2k;this.s2k.read(a, -d);if(s2k.s2kLength+d>8&255),d=d+String.fromCharCode(e&255),f=f+a+String.fromCharCode(c),a=new openpgp_type_mpi,b=openpgp_crypto_asymetricEncrypt(c,b,a.create(openpgp_encoding_eme_pkcs1_encode(d,b[0].mpiByteLength))),c=0;ca[e].charCodeAt()?(packet_length=a[e++].charCodeAt(),f=1):192<=a[e].charCodeAt()&&224>a[e].charCodeAt()?(packet_length=(a[e++].charCodeAt()-192<<8)+a[e++].charCodeAt()+192,f=2):223a[e].charCodeAt()? -(packet_length=1<<(a[e++].charCodeAt()&31),f=1):(f=5,e++,packet_length=a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt());a[e++].charCodeAt();packet_length--;f++;this.userattributes[0]=[];this.userattributes[0]=a.substring(e,e+packet_length);e+=packet_length;d+=f+packet_length}this.packetLength=e-b;return this};this.read_nodes=function(a,b,c,d){this.parentNode=a;for(var e=c,f=d;b.length!=e;){var h=openpgp_packet.read_packet(b,e,f);if(null==h){util.print_error("openpgp.packet.userattribute.js\n[user_attr] parsing ends here @:"+ -e+" l:"+f);break}else switch(h.tagType){case 2:15h.signatureType?this.certificationSignatures[this.certificationSignatures.length]=h:32==h.signatureType&&(this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=h);e+=h.packetLength+h.headerLength;f=d-(e-c);break;default:return this.data=b,this.position=c-a.packetLength,this.len=e-c}}this.data=b;this.position=c-a.packetLength;return this.len=e-c};this.toString=function(){for(var a="5.12. User Attribute Packet (Tag 17)\n AttributePackets: (count = "+ -this.userattributes.length+")\n",b=0;bd&&util.print_debug("openpgp.packet.signature.js\n_raw_read_signature_sub_packet length < 0 @:"+a);var e=a,f=0;192>b[e].charCodeAt()?f=b[e++].charCodeAt():192<=b[e].charCodeAt()&&224>b[e].charCodeAt()?f=(b[e++].charCodeAt()-192<<8)+b[e++].charCodeAt()+192:223b[e].charCodeAt()?f=1<<(b[e++].charCodeAt()&31):255>b[e].charCodeAt()&&(e++,f=b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt()); -var h=b[e++].charCodeAt()&127;switch(h){case 2:this.creationTime=new Date(1E3*(b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt()));break;case 3:this.signatureExpirationTime=b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt();this.signatureNeverExpires=0==this.signature_expiration_time;break;case 4:this.exportable=1==b[e++].charCodeAt();break;case 5:this.trustLevel=b[e++].charCodeAt();this.trustAmount=b[e++].charCodeAt(); -break;case 6:this.regular_expression=new String;for(h=0;hh;h++)this.revocationKeyFingerprint=b[e++].charCodeAt();break;case 16:this.issuerKeyId=b.substring(e,e+8);e+=8;break;case 20:this.notationFlags=b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt();d=b[e++].charCodeAt()<<8|b[e++].charCodeAt();f=b[e++].charCodeAt()<<8|b[e++].charCodeAt();this.notationName="";for(h=0;h>24&255)+String.fromCharCode(b>>16&255)+String.fromCharCode(b>>8&255)+String.fromCharCode(b&255)),g=a(16,d.getKeyId()),h=h+String.fromCharCode(b.length+g.length>>8&255),h=h+String.fromCharCode(b.length+g.length&255),h=h+b+g,b=""+String.fromCharCode(4),b=b+String.fromCharCode(255),b=b+String.fromCharCode(h.length>>24),b=b+String.fromCharCode(h.length>>16&255),b=b+String.fromCharCode(h.length>>8&255),b=b+String.fromCharCode(h.length&255),g=String.fromCharCode(0), -g=g+String.fromCharCode(0),k=openpgp_crypto_hashData(f,c+h+b);util.print_debug("DSA Signature is calculated with:|"+c+h+b+"|\n"+util.hexstrdump(c+h+b)+"\n hash:"+util.hexstrdump(k));g+=k.charAt(0);g+=k.charAt(1);g+=openpgp_crypto_signData(f,d.privateKeyPacket.publicKey.publicKeyAlgorithm,e.MPIs,d.privateKeyPacket.secMPIs,c+h+b);return{openpgp:openpgp_packet.write_packet_header(2,(h+g).length)+h+g,hash:util.get_hashAlgorithmString(f)}};this.verify=function(b,a){switch(this.signatureType){case 0:if(4== -this.version){var d;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>>24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.obj.publicKeyPacket.MPIs,b.substring(i)+this.signatureData+d)}if(3==this.version)return!1;case 1:if(4== -this.version)return d=""+String.fromCharCode(this.version),d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>>16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.obj.publicKeyPacket.MPIs,b+this.signatureData+d);if(3==this.version)return!1;case 2:if(3==this.version)return!1; -d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>>24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.obj.publicKeyPacket.MPIs,this.signatureData+d);case 16:case 17:case 18:case 19:case 48:return d=""+String.fromCharCode(this.version), -d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>>16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);case 24:if(3==this.version)return!1;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>> -24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);case 25:case 31:case 32:case 40:return d=""+String.fromCharCode(this.version),d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>> -16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);default:util.print_error("openpgp.packet.signature.js\nsignature verification for type"+this.signatureType+" not implemented")}};this.read_packet=function(b,a,d){this.data=b.substring(a,a+d);if(0>d)return util.print_debug("openpgp.packet.signature.js\nopenpgp_packet_signature read_packet length < 0 @:"+ -a),null;var e=a;this.packetLength=d;this.version=b[e++].charCodeAt();switch(this.version){case 3:5!=b[e++].charCodeAt()&&util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material. MUST be 5. @:"+(e-1));this.signatureType=b[e++].charCodeAt();this.creationTime=new Date(1E3*(b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt()));this.signatureData=b.substring(a,e);this.keyId=b.substring(e,e+8);e+=8;this.publicKeyAlgorithm= -b[e++].charCodeAt();this.hashAlgorithm=b[e++].charCodeAt();this.signedHashValue=b[e++].charCodeAt()<<8|b[e++].charCodeAt();d=0;0this.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(var f=0;fthis.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(f=0;fd&&util.print_debug("openpgp.packet.signature.js\n_raw_read_signature_sub_packet length < 0 @:"+b);var e=b,f=0;192>a[e].charCodeAt()?f=a[e++].charCodeAt():192<=a[e].charCodeAt()&&224>a[e].charCodeAt()?f=(a[e++].charCodeAt()-192<<8)+a[e++].charCodeAt()+192:223a[e].charCodeAt()?f=1<<(a[e++].charCodeAt()&31):255>a[e].charCodeAt()&&(e++,f=a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt()); +var g=a[e++].charCodeAt()&127;switch(g){case 2:this.creationTime=new Date(1E3*(a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt()));break;case 3:this.signatureExpirationTime=a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt();this.signatureNeverExpires=0==this.signature_expiration_time;break;case 4:this.exportable=1==a[e++].charCodeAt();break;case 5:this.trustLevel=a[e++].charCodeAt();this.trustAmount=a[e++].charCodeAt(); +break;case 6:this.regular_expression=new String;for(g=0;gg;g++)this.revocationKeyFingerprint=a[e++].charCodeAt();break;case 16:this.issuerKeyId=a.substring(e,e+8);e+=8;break;case 20:this.notationFlags=a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt();d=a[e++].charCodeAt()<<8|a[e++].charCodeAt();f=a[e++].charCodeAt()<<8|a[e++].charCodeAt();this.notationName="";for(g=0;g>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255)),h=b(16,d.getKeyId()),g=g+String.fromCharCode(a.length+h.length>>8&255),g=g+String.fromCharCode(a.length+h.length&255),g=g+a+h,a=""+String.fromCharCode(4),a=a+String.fromCharCode(255),a=a+String.fromCharCode(g.length>>24),a=a+String.fromCharCode(g.length>>16&255),a=a+String.fromCharCode(g.length>>8&255),a=a+String.fromCharCode(g.length&255),h=String.fromCharCode(0), +h=h+String.fromCharCode(0),k=openpgp_crypto_hashData(f,c+g+a);util.print_debug("DSA Signature is calculated with:|"+c+g+a+"|\n"+util.hexstrdump(c+g+a)+"\n hash:"+util.hexstrdump(k));h+=k.charAt(0);h+=k.charAt(1);h+=openpgp_crypto_signData(f,d.privateKeyPacket.publicKey.publicKeyAlgorithm,e.MPIs,d.privateKeyPacket.secMPIs,c+g+a);return{openpgp:openpgp_packet.write_packet_header(2,(g+h).length)+g+h,hash:util.get_hashAlgorithmString(f)}};this.verify=function(a,b){switch(this.signatureType){case 0:if(4== +this.version){var d;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>>24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.obj.publicKeyPacket.MPIs,a.substring(i)+this.signatureData+d)}if(3==this.version)return!1;case 1:if(4== +this.version)return d=""+String.fromCharCode(this.version),d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>>16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.obj.publicKeyPacket.MPIs,a+this.signatureData+d);if(3==this.version)return!1;case 2:if(3==this.version)return!1; +d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>>24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.obj.publicKeyPacket.MPIs,this.signatureData+d);case 16:case 17:case 18:case 19:case 48:return d=""+String.fromCharCode(this.version), +d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>>16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.MPIs,a+this.signatureData+d);case 24:if(3==this.version)return!1;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>> +24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.MPIs,a+this.signatureData+d);case 25:case 31:case 32:case 40:return d=""+String.fromCharCode(this.version),d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>> +16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,b.MPIs,a+this.signatureData+d);default:util.print_error("openpgp.packet.signature.js\nsignature verification for type"+this.signatureType+" not implemented")}};this.read_packet=function(a,b,d){this.data=a.substring(b,b+d);if(0>d)return util.print_debug("openpgp.packet.signature.js\nopenpgp_packet_signature read_packet length < 0 @:"+ +b),null;var e=b;this.packetLength=d;this.version=a[e++].charCodeAt();switch(this.version){case 3:5!=a[e++].charCodeAt()&&util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material. MUST be 5. @:"+(e-1));this.signatureType=a[e++].charCodeAt();this.creationTime=new Date(1E3*(a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt()));this.signatureData=a.substring(b,e);this.keyId=a.substring(e,e+8);e+=8;this.publicKeyAlgorithm= +a[e++].charCodeAt();this.hashAlgorithm=a[e++].charCodeAt();this.signedHashValue=a[e++].charCodeAt()<<8|a[e++].charCodeAt();d=0;0this.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(var f=0;fthis.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(f=0;fthis.publicKeyAlgorithm?d=2:16==this.publicKeyAlgorithm?d=3:17==this.publicKeyAlgorithm&&(d=4);this.MPIs=[];for(var e=0;ethis.publicKeyAlgorithm?d=2:16==this.publicKeyAlgorithm?d=3:17==this.publicKeyAlgorithm&&(d=4);this.MPIs=[];for(e=0;ethis.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a, -d,c-2-(d-b)),d+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(a,d,c-2-(d-b)),d+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(a,d,c-2-(d-b)),d+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(a,d,c-2-(d-b)),d+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,d,c-2-(d-b)),d+=this.secMPIs[0].packetLength; -else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,d,c-2-(d-b)),d+=this.secMPIs[0].packetLength;this.checksum=[];this.checksum[0]=a[d++].charCodeAt();this.checksum[1]=a[d++].charCodeAt()}else this.encryptedMPIData=a.substring(d,c);return this};this.decryptSecretMPIs=function(a){if(this.hasUnencryptedSecretKeyData)return this.secMPIs;var b=this.s2k.produce_key(a),c="";switch(this.symmetricEncryptionAlgorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"), -!1;case 2:c=normal_cfb_decrypt(function(b,a){return des(a,b,1,null,0)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 3:c=normal_cfb_decrypt(function(b,a){var c=new openpgp_symenc_cast5;c.setKey(a);return c.encrypt(util.str2bin(b))},this.IVLength,util.str2bin(b.substring(0,16)),this.encryptedMPIData,this.IV);break;case 4:c=normal_cfb_decrypt(function(b,a){return(new Blowfish(a)).encrypt(b)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 7:case 8:case 9:c=16;8==this.symmetricEncryptionAlgorithm&& -(c=24,b=this.s2k.produce_key(a,c));9==this.symmetricEncryptionAlgorithm&&(c=32,b=this.s2k.produce_key(a,c));c=normal_cfb_decrypt(function(b,a){return AESencrypt(util.str2bin(b),a)},this.IVLength,keyExpansion(b.substring(0,c)),this.encryptedMPIData,this.IV);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm), -!1}if(null==c)return util.print_error("openpgp.packet.keymaterial.js\ncleartextMPIs was null"),!1;a=c.length;if(254==this.s2kUsageConventions&&str_sha1(c.substring(0,c.length-20))==c.substring(c.length-20))a-=20;else if(254!=this.s2kUsageConventions&&util.calc_checksum(c.substring(0,c.length-2))==(c.charCodeAt(c.length-2)<<8|c.charCodeAt(c.length-1)))a-=2;else return!1;if(0this.publicKey.publicKeyAlgorithm)b=0,this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi, -this.secMPIs[0].read(c,0,a),b+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(c,b,a-b),b+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(c,b,a-b),b+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(c,b,a-b),b+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,c);else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs= -[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,a);return!0};this.read_nodes=function(a,b,c,d){this.parentNode=a;if(14==this.tagType){for(var a=c,e=null;b.length!=a;)if(d=b.length-a,e=openpgp_packet.read_packet(b,a,d),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_pub]parsing ends here @:"+a+" l:"+d);break}else switch(e.tagType){case 2:if(24==e.signatureType){this.subKeySignature=e;a+=e.packetLength+e.headerLength;break}else if(40==e.signatureType){this.subKeyRevocationSignature= -e;a+=e.packetLength+e.headerLength;break}else util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+e.toString());default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}if(7==this.tagType){for(a=c;b.length!=a;)if(e=openpgp_packet.read_packet(b,a,d-(a-c)),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_priv] parsing ends here @:"+a);break}else switch(e.tagType){case 2:24== -e.signatureType?this.subKeySignature=e:40==e.signatureType&&(this.subKeyRevocationSignature[this.subKeyRevocationSignature]=e);a+=e.packetLength+e.headerLength;break;default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}util.print_error("openpgp.packet.keymaterial.js\nunknown parent node for a key material packet "+a.tagType)};this.verifyKey=function(){if(14==this.tagType){if(null==this.subKeySignature)return 0; -if(4==this.subKeySignature.version&&null!=this.subKeySignature.keyNeverExpires&&!this.subKeySignature.keyNeverExpires&&new Date(1E3*this.subKeySignature.keyExpirationTime+this.creationTime.getTime())this.publicKeyAlgorithm){var a=this.MPIs[0].substring(this.MPIs[0].mpiByteLength-8);util.print_debug("openpgp.msg.publickey read_nodes:\nV3 key ID: "+ -a);return a}};this.getFingerprint=function(){if(4==this.version)return tohash=String.fromCharCode(153)+String.fromCharCode(this.packetdata.length>>8&255)+String.fromCharCode(this.packetdata.length&255)+this.packetdata,util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm),str_sha1(tohash,tohash.length);if(3==this.version&&0this.publicKeyAlgorithm)return MD5(this.MPIs[0].MPI)}; -this.write_private_key=function(a,b,c,d,e,f){this.symmetricEncryptionAlgorithm=e;e=String.fromCharCode(4);e+=f;switch(a){case 1:e+=String.fromCharCode(a);e+=b.n.toMPI();e+=b.ee.toMPI();if(c)switch(e+=String.fromCharCode(254),e+=String.fromCharCode(this.symmetricEncryptionAlgorithm),e+=String.fromCharCode(3),e+=String.fromCharCode(d),a=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI(),b=str_sha1(a),util.print_debug_hexstr_dump("write_private_key sha1: ",b),f=openpgp_crypto_getRandomBytes(8),util.print_debug_hexstr_dump("write_private_key Salt: ", -f),e=e+f+String.fromCharCode(96),util.print_debug("write_private_key c: 96"),c=(new openpgp_type_s2k).write(3,d,c,f,96),this.symmetricEncryptionAlgorithm){case 3:this.IVLength=8;this.IV=openpgp_crypto_getRandomBytes(this.IVLength);ciphertextMPIs=normal_cfb_encrypt(function(b,a){var c=new openpgp_symenc_cast5;c.setKey(a);return c.encrypt(util.str2bin(b))},this.IVLength,util.str2bin(c.substring(0,16)),a+b,this.IV);e+=this.IV+ciphertextMPIs;break;case 7:case 8:case 9:this.IVLength=16,this.IV=openpgp_crypto_getRandomBytes(this.IVLength), -ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.IVLength,c,a+b,this.IV),e+=this.IV+ciphertextMPIs}else e+=String.fromCharCode(0),e+=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI(),c=util.calc_checksum(b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI()),e+=String.fromCharCode(c/256)+String.fromCharCode(c%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+c);break;default:e="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+a)}c=openpgp_packet.write_packet_header(5, -e.length);return{string:c+e,header:c,body:e}};this.write_public_key=function(a,b,c){var d=String.fromCharCode(4),d=d+c;switch(a){case 1:d+=String.fromCharCode(1);d+=b.n.toMPI();d+=b.ee.toMPI();break;default:util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+a)}a=openpgp_packet.write_packet_header(6,d.length);return{string:a+d,header:a,body:d}}} -function openpgp_packet_marker(){this.tagType=10;this.read_packet=function(a,b){this.packetLength=3;return 80==a[b].charCodeAt()&&71==a[b+1].charCodeAt()&&80==a[b+2].charCodeAt()?this:null};this.toString=function(){return'5.8. Marker Packet (Obsolete Literal Packet) (Tag 10)\n packet reads: "PGP"\n'}} -function openpgp_packet_modificationdetectioncode(){this.tagType=19;this.hash=null;this.read_packet=function(a,b,c){this.packetLength=c;if(20!=c)return util.print_error("openpgp.packet.modificationdetectioncode.js\ninvalid length for a modification detection code packet!"+c),null;this.hash=a.substring(b,b+20);return this};this.toString=function(){return"5.14 Modification detection code packet\n bytes ("+this.hash.length+"): ["+util.hexstrdump(this.hash)+"]"}} -function _openpgp_packet(){function a(b){result="";192>b?result+=String.fromCharCode(b):191b?(result+=String.fromCharCode((b-192>>8)+192),result+=String.fromCharCode(b-192&255)):(result+=String.fromCharCode(255),result+=String.fromCharCode(b>>24&255),result+=String.fromCharCode(b>>16&255),result+=String.fromCharCode(b>>8&255),result+=String.fromCharCode(b&255));return result}this.encode_length=a;this.write_old_packet_header=function(b,a){var d="";256>a?(d+=String.fromCharCode(128|b<<2),d+= -String.fromCharCode(a)):(65536>a?(d+=String.fromCharCode(b<<2|129),d+=String.fromCharCode(a>>8)):(d+=String.fromCharCode(b<<2|130),d+=String.fromCharCode(a>>24&255),d+=String.fromCharCode(a>>16&255),d+=String.fromCharCode(a>>8&255)),d+=String.fromCharCode(a&255));return d};this.write_packet_header=function(b,c){var d;d=""+String.fromCharCode(192|b);return d+=a(c)};this.read_packet=function(b,a){if(null==b||b.length<=a||2>b.substring(a).length||0==(b[a].charCodeAt()&128))return util.print_error("Error during parsing. This message / key is propably not containing a valid OpenPGP format."), -null;var d=a,e=-1,f=-1,f=0;0!=(b[d].charCodeAt()&64)&&(f=1);var h;f?e=b[d].charCodeAt()&63:(e=(b[d].charCodeAt()&63)>>2,h=b[d].charCodeAt()&3);d++;var g=null,k=-1;if(f)if(192>b[d].charCodeAt())packet_length=b[d++].charCodeAt(),util.print_debug("1 byte length:"+packet_length);else if(192<=b[d].charCodeAt()&&224>b[d].charCodeAt())packet_length=(b[d++].charCodeAt()-192<<8)+b[d++].charCodeAt()+192,util.print_debug("2 byte length:"+packet_length);else if(223b[d].charCodeAt()){packet_length= -1<<(b[d++].charCodeAt()&31);util.print_debug("4 byte length:"+packet_length);k=d+packet_length;for(g=b.substring(d,d+packet_length);;)if(192>b[k].charCodeAt()){f=b[k++].charCodeAt();packet_length+=f;g+=b.substring(k,k+f);k+=f;break}else if(192<=b[k].charCodeAt()&&224>b[k].charCodeAt()){f=(b[k++].charCodeAt()-192<<8)+b[k++].charCodeAt()+192;packet_length+=f;g+=b.substring(k,k+f);k+=f;break}else if(223b[k].charCodeAt())f=1<<(b[k++].charCodeAt()&31),packet_length+=f,g+=b.substring(k, -k+f),k+=f;else{k++;f=b[k++].charCodeAt()<<24|b[k++].charCodeAt()<<16|b[k++].charCodeAt()<<8|b[k++].charCodeAt();g+=b.substring(k,k+f);packet_length+=f;k+=f;break}}else d++,packet_length=b[d++].charCodeAt()<<24|b[d++].charCodeAt()<<16|b[d++].charCodeAt()<<8|b[d++].charCodeAt();else switch(h){case 0:packet_length=b[d++].charCodeAt();break;case 1:packet_length=b[d++].charCodeAt()<<8|b[d++].charCodeAt();break;case 2:packet_length=b[d++].charCodeAt()<<24|b[d++].charCodeAt()<<16|b[d++].charCodeAt()<<8| -b[d++].charCodeAt()}-1==k&&(k=packet_length);null==g&&(g=b.substring(d,d+k));switch(e){case 0:break;case 1:e=new openpgp_packet_encryptedsessionkey;if(null!=e.read_pub_key_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 2:e=new openpgp_packet_signature;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 3:e=new openpgp_packet_encryptedsessionkey;if(null!=e.read_symmetric_key_packet(g,0,packet_length))return e.headerLength= -d-a,e.packetLength=k,e;break;case 4:e=new openpgp_packet_onepasssignature;if(e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 5:e=new openpgp_packet_keymaterial;e.header=b.substring(a,d);if(null!=e.read_tag5(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 6:e=new openpgp_packet_keymaterial;e.header=b.substring(a,d);if(null!=e.read_tag6(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 7:e=new openpgp_packet_keymaterial; -if(null!=e.read_tag7(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 8:e=new openpgp_packet_compressed;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 9:e=new openpgp_packet_encrypteddata;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 10:e=new openpgp_packet_marker;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 11:e=new openpgp_packet_literaldata; -if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.header=b.substring(a,d),e.packetLength=k,e;break;case 12:break;case 13:e=new openpgp_packet_userid;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 14:e=new openpgp_packet_keymaterial;e.header=b.substring(a,d);if(null!=e.read_tag14(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 17:e=new openpgp_packet_userattribute;if(null!=e.read_packet(g,0,packet_length))return e.headerLength= -d-a,e.packetLength=k,e;break;case 18:e=new openpgp_packet_encryptedintegrityprotecteddata;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;case 19:e=new openpgp_packet_modificationdetectioncode;if(null!=e.read_packet(g,0,packet_length))return e.headerLength=d-a,e.packetLength=k,e;break;default:return util.print_error("openpgp.packet.js\n[ERROR] openpgp_packet: failed to parse packet @:"+d+"\nchar:'"+util.hexstrdump(b.substring(d))+"'\ninput:"+util.hexstrdump(b)), -null}}}var openpgp_packet=new _openpgp_packet; -function openpgp_packet_literaldata(){this.tagType=11;this.read_packet=function(a,b,c){this.packetLength=c;this.format=a[b];this.filename=a.substr(b+2,a.charCodeAt(b+1));this.date=new Date(1E3*parseInt(a.substr(b+2+a.charCodeAt(b+1),4)));this.data=a.substring(b+6+a.charCodeAt(b+1));return this};this.toString=function(){return"5.9. Literal Data Packet (Tag 11)\n length: "+this.packetLength+"\n format: "+this.format+"\n filename:"+this.filename+"\n date: "+this.date+"\n data: |"+ -this.data+"|\n rdata: |"+this.real_data+"|\n"};this.write_packet=function(a){a=a.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");this.filename="msg.txt";this.date=new Date;this.format="t";var b=openpgp_packet.write_packet_header(11,a.length+6+this.filename.length),b=b+this.format,b=b+String.fromCharCode(this.filename.length),b=b+this.filename,b=b+String.fromCharCode(Math.round(this.date.getTime()/1E3)>>24&255),b=b+String.fromCharCode(Math.round(this.date.getTime()/1E3)>>16&255),b=b+String.fromCharCode(Math.round(this.date.getTime()/ -1E3)>>8&255),b=b+String.fromCharCode(Math.round(this.date.getTime()/1E3)&255);this.data=a;return b+a}} -function openpgp_packet_compressed(){this.tagType=8;this.read_packet=function(a,b,c){this.packetLength=c;var d=b;this.type=a.charCodeAt(d++);this.compressedData=a.substring(b+1,b+c);return this};this.toString=function(){return"5.6. Compressed Data Packet (Tag 8)\n length: "+this.packetLength+"\n Compression Algorithm = "+this.type+"\n Compressed Data: Byte ["+util.hexstrdump(this.compressedData)+"]\n"};this.compress=function(a,b){this.type=a;this.decompressedData=b;switch(this.type){case 0:this.compressedData= -this.decompressedData;break;case 1:util.print_error("Compression algorithm ZIP [RFC1951] is not implemented.");break;case 2:util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented.");break;case 3:util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}this.packetLength=this.compressedData.length+1;return this.compressedData};this.decompress=function(){if(null!=this.decompressedData)return this.decompressedData; -if(null==this.type)return null;switch(this.type){case 0:this.decompressedData=this.compressedData;break;case 1:var a=this.compressedData,a=s2r(a).replace(/\n/g,""),a=new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(a)),a=unescape(a.deflate()[0][0]),a=openpgp_packet.read_packet(a,0,a.length);util.print_info("Decompressed packet [Type 1-ZIP]: "+a);this.decompressedData=a.data;break;case 2:8==this.compressedData.charCodeAt(0)%16?(a=this.compressedData.substring(0,this.compressedData.length-4),a=s2r(a).replace(/\n/g, -""),a=JXG.decompress(a),a=openpgp_packet.read_packet(a,0,a.length),util.print_info("Decompressed packet [Type 2-ZLIB]: "+a),this.decompressedData=a.data):util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method.");break;case 3:util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}util.print_debug("decompressed:"+util.hexstrdump(this.decompressedData));return this.decompressedData}; -this.write_packet=function(a,b){this.decompressedData=b;if(null==a)this.type=1;var c=String.fromCharCode(this.type)+this.compress(this.type);return openpgp_packet.write_packet_header(8,c.length)+c}} -function openpgp_packet_userid(){this.tagType=13;this.certificationSignatures=[];this.certificationRevocationSignatures=[];this.revocationSignatures=[];this.parentNode=null;this.hasCertificationRevocationSignature=function(a){for(var b=0;bthis.certificationSignatures[b].creationTime){var e=String.fromCharCode(153)+a.header.substring(1)+a.data+String.fromCharCode(180)+String.fromCharCode(this.text.length>>24&255)+String.fromCharCode(this.text.length>>16&255)+String.fromCharCode(this.text.length>>8&255)+String.fromCharCode(this.text.length&255)+this.text;if(d.verify(e,c)){result[b]=this.certificationSignatures[b].issuerKeyId==a.getKeyId()?6:3;continue}}e=String.fromCharCode(153)+a.header.substring(1)+a.data+String.fromCharCode(180)+ -String.fromCharCode(this.text.length>>24&255)+String.fromCharCode(this.text.length>>16&255)+String.fromCharCode(this.text.length>>8&255)+String.fromCharCode(this.text.length&255)+this.text;result[b]=this.certificationSignatures[b].verify(e,c)?4:0}}else if(3==this.certificationSignatures[b].version)if(null==this.certificationSignatures[b].keyId)result[b]=0;else if(c=openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[b].keyId),null==c||0==c.length)result[b]=2;else if(c=publicKey.obj.getSigningKey(), -null==c)result[b]=0;else{d=this.hasCertificationRevocationSignature(this.certificationSignatures[b].keyId);if(null!=d&&d.creationTime>this.certificationSignatures[b].creationTime&&(e=String.fromCharCode(153)+this.publicKeyPacket.header.substring(1)+this.publicKeyPacket.data+this.text,d.verify(e,c))){result[b]=d.keyId==a.getKeyId()?6:3;continue}e=String.fromCharCode(153)+a.header.substring(1)+a.data+this.text;result[b]=this.certificationSignatures[b].verify(e,c)?4:0}else result[b]=0;return result}; -this.verify=function(a){a=this.verifyCertificationSignatures(a);return-1!=a.indexOf(6)?2:-1!=a.indexOf(5)?1:0};this.read_packet=function(a,b,c){this.text="";this.packetLength=c;for(var d=0;dh.signatureType){this.certificationSignatures[this.certificationSignatures.length]=h;break}else if(48==h.signatureType){this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=h;break}else if(24==h.signatureType){this.certificationSignatures[this.certificationSignatures.length]=h;break}else util.debug("unknown sig t: "+h.signatureType+"@"+(e-(h.packetLength+h.headerLength))); -default:return this.data=b,this.position=c-a.packetLength,this.len=e-c-(h.headerLength+h.packetLength)}}this.data=b;this.position=c-a.packetLength;return this.len=e-c-(h.headerLength+h.packetLength)}if(5==a.tagType){this.parentNode=a;for(e=c;b.length!=e;)if(h=openpgp_packet.read_packet(b,e,f-(e-c)),null==h){util.print_error("parsing ends here @:"+e+" l:"+f);break}else switch(e+=h.packetLength+h.headerLength,h.tagType){case 2:15h.signatureType?this.certificationSignatures[this.certificationSignatures.length]= -h:48==h.signatureType&&(this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=h);default:return this.data=b,this.position=c-a.packetLength,this.len=e-c-(h.headerLength+h.packetLength)}}else util.print_error("unknown parent node for a userId packet "+a.tagType)}} -function openpgp_packet_encryptedintegrityprotecteddata(){this.tagType=18;this.hash=this.decrytpedData=this.encryptedData=this.packetLength=this.version=null;this.write_packet=function(a,b,c){var d=openpgp_crypto_getPrefixRandom(a),e=d+d.charAt(d.length-2)+d.charAt(d.length-1),c=c+String.fromCharCode(211),c=c+String.fromCharCode(20);util.print_debug_hexstr_dump("data to be hashed:",e+c);c+=str_sha1(e+c);util.print_debug_hexstr_dump("hash:",c.substring(c.length-20,c.length));a=openpgp_crypto_symmetricEncrypt(d, -a,b,c,!1).substring(0,e.length+c.length);b=openpgp_packet.write_packet_header(18,a.length+1)+String.fromCharCode(1);this.encryptedData=a;return b+a};this.read_packet=function(a,b,c){this.packetLength=c;this.version=a[b].charCodeAt();if(1!=this.version)return util.print_error("openpgp.packet.encryptedintegrityprotecteddata.js\nunknown encrypted integrity protected data packet version: "+this.version+" , @ "+b+"hex:"+util.hexstrdump(a)),null;this.encryptedData=a.substring(b+1,b+1+c);util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\n"+ -this.toString());return this};this.toString=function(){var a="";openpgp.config.debug&&(a=" data: Bytes ["+util.hexstrdump(this.encryptedData)+"]");return"5.13. Sym. Encrypted Integrity Protected Data Packet (Tag 18)\n length: "+this.packetLength+"\n version: "+this.version+"\n"+a};this.decrypt=function(a,b){this.decryptedData=openpgp_crypto_symmetricDecrypt(a,b,this.encryptedData,!1);this.hash=str_sha1(openpgp_crypto_MDCSystemBytes(a,b,this.encryptedData)+this.decryptedData.substring(0, +this.reasonForRevocationFlag+"\n Reason :"+this.reasonForRevocationString+"\nMPI:\n",b=0;b>4)+this.EXPBIAS;this.s2kLength=10;break;default:util.print_error("unknown s2k type! "+this.type)}return this}; -this.write=function(a,b,c,d,e){this.type=a;if(3==this.type)this.saltValue=d,this.hashAlgorithm=b,this.count=16+(e&15)<<(e>>4)+6,this.s2kLength=10;return this.produce_key(c)};this.produce_key=function(a,b){if(0==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,a);if(1==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+a);if(3==this.type){var c=[];for(c[0]=this.saltValue+a;c.length*(this.saltValue+a).length -this.count&&(c=c.substr(0,this.count));return b&&(24==b||32==b)?openpgp_crypto_hashData(this.hashAlgorithm,c)+openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+c):openpgp_crypto_hashData(this.hashAlgorithm,c)}return null}} -function openpgp_type_mpi(){this.data=this.mpiByteLength=this.mpiBitLength=this.MPI=null;this.read=function(a,b){var c=b;this.mpiBitLength=a[c++].charCodeAt()<<8|a[c++].charCodeAt();this.mpiByteLength=(this.mpiBitLength-this.mpiBitLength%8)/8;0!=this.mpiBitLength%8&&this.mpiByteLength++;this.MPI=a.substring(c,c+this.mpiByteLength);this.data=a.substring(b,b+2+this.mpiByteLength);this.packetLength=this.mpiByteLength+2;return this};this.toBigInteger=function(){return new BigInteger(util.hexstrdump(this.MPI), -16)};this.toString=function(){var a=" MPI("+this.mpiBitLength+"b/"+this.mpiByteLength+"B) : 0x",a=a+util.hexstrdump(this.MPI);return a+"\n"};this.create=function(a){this.MPI=a;var b=8*(a.length-1),c;a:for(var d=a.charCodeAt(0),e=0;9>e;e++)if(0==d>>e){c=e;break a}this.mpiBitLength=b+c;this.mpiByteLength=a.length;return this};this.toBin=function(){var a=String.fromCharCode(this.mpiBitLength>>8&255),a=a+String.fromCharCode(this.mpiBitLength&255);return a+=this.MPI};this.getByteLength=function(){return this.mpiByteLength}} -function openpgp_type_keyid(){this.read_packet=function(a,b){this.bytes=a.substring(b,b+8);return this};this.toString=function(){return util.hexstrdump(this.bytes)}} -function openpgp_msg_message(){this.text="";this.decrypt=function(a,b){return this.decryptAndVerifySignature(a,b).text};this.decryptAndVerifySignature=function(a,b,c){if(null==a||null==b||""==b)return null;a=b.decrypt(this,a.keymaterial);if(null==a)return null;var d,b=0,e=a.length,f=[];for(util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",a);b!=a.length&&null!=(d=openpgp_packet.read_packet(a,b,e));){if(8==d.tagType)this.text=d.decompress(),a=d.decompress();util.print_debug(d.toString()); -b+=d.headerLength+d.packetLength;38d.signatureType){if(!c||0==c.length)c=openpgp.keyring.getPublicKeysForKeyId(d.issuerKeyId);0==c.length?(util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(d.issuerKeyId)+". Public key not found in keyring."),f[f.length]=!1):d.verify(this.text.replace(/\r\n/g, -"\n").replace(/\n/g,"\r\n"),c[0])&&c[0].obj.validate()?(util.print_info("Found Good Signature from "+c[0].obj.userIds[0].text+" (0x"+util.hexstrdump(c[0].obj.getKeyId()).substring(8)+")"),f[f.length]=!0):(util.print_error("Signature verification failed: Bad Signature from "+c[0].obj.userIds[0].text+" (0x"+util.hexstrdump(c[0].obj.getKeyId()).substring(8)+")"),f[f.length]=!1)}}if(""==this.text)this.text=a;return{text:this.text,validSignatures:f}};this.verifySignature=function(a){var b=!1;if(2==this.type){if(!a|| -0==a.length)if(4==this.signature.version)a=openpgp.keyring.getPublicKeysForKeyId(this.signature.issuerKeyId);else if(3==this.signature.version)a=openpgp.keyring.getPublicKeysForKeyId(this.signature.keyId);else return util.print_error("unknown signature type on message!"),!1;if(0==a.length)util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(this.signature.issuerKeyId)+". Public key not found in keyring.");else for(var c=0;ce.length;)e="0"+e;b.push(" "+e);f++;0==f%32&&b.push("\n ")}return b.join("")};this.hexstrdump=function(a){if(null==a)return"";for(var b=[],c=a.length,d=0,e;de.length;)e= -"0"+e;b.push(""+e)}return b.join("")};this.hex2bin=function(a){for(var b="",c=0;ce.length;)e="0"+e;b.push(""+e)}return b.join("")};this.str2bin=function(a){for(var b=[],c=0;c

'+ -a.replace(/\n/g,"
")+"

"))};this.print_debug_hexstr_dump=function(a,b){openpgp.config.debug&&(a+=this.hexstrdump(b),a=openpgp_encoding_html_encode(a),showMessages('

'+a.replace(/\n/g,"
")+"

"))};this.print_error=function(a){a=openpgp_encoding_html_encode(a);showMessages('

ERROR:\t'+ -a.replace(/\n/g,"
")+"

")};this.print_info=function(a){a=openpgp_encoding_html_encode(a);showMessages('

INFO:\t'+a.replace(/\n/g,"
")+"

")};this.print_warning=function(a){a=openpgp_encoding_html_encode(a);showMessages('

WARNING:\t'+ -a.replace(/\n/g,"
")+"

")};this.getLeftNBits=function(a,b){var c=b%8;return 0==c?a.substring(0,b/8):this.shiftRight(a.substring(0,(b-c)/8+1),8-c)};this.shiftRight=function(a,b){var c=util.str2bin(a);if(0!=b%8)for(var d=c.length-1;0<=d;d--)c[d]>>=b%8,0>=1;0==D&&(D=b(),a=D&1,D=D>>1|128);return a}function d(b){for(var a=0,d=b;d--;)a=a<<1|c();b&&(a=K[a]>>8-b);return a}function e(b){T++;t[r++]=b;q.push(String.fromCharCode(b));32768==r&&(r=0)}function f(){this.b1=this.b0=0;this.jump=null;this.jumppos=-1}function h(){for(;;){if(V[O]>=pa)return-1;if(qa[V[O]]==O)return V[O]++;V[O]++}}function g(){var b=Z[aa],a;m&&document.write("
len:"+O+" treepos:"+ -aa);if(17==O)return-1;aa++;O++;a=h();m&&document.write("
IsPat "+a);if(0<=a)b.b0=a,m&&document.write("
b0 "+b.b0);else if(b.b0=32768,m&&document.write("
b0 "+b.b0),g())return-1;a=h();if(0<=a)b.b1=a,m&&document.write("
b1 "+b.b1),b.jump=null;else if(b.b1=32768,m&&document.write("
b1 "+b.b1),b.jump=Z[aa],b.jumppos=aa,g())return-1;O--;return 0}function k(b,a,c,d){m&&document.write("currentTree "+b+" numval "+a+" lengths "+c+" show "+d);Z=b;aa=0;qa=c;pa=a;for(b=0;17>b;b++)V[b]=0;O=0;if(g())return m&& -alert("invalid huffman tree\n"),-1;if(m){document.write("
Tree: "+Z.length);for(b=0;32>b;b++)document.write("Places["+b+"].b0="+Z[b].b0+"
"),document.write("Places["+b+"].b1="+Z[b].b1+"
")}return 0}function j(b){for(var a,d,e=0,f=b[e];;)if(a=c(),m&&document.write("b="+a),a){if(!(f.b1&32768))return m&&document.write("ret1"),f.b1;f=f.jump;a=b.length;for(d=0;d>1,23g)e(g);else if(256==g)break;else{var A;g-=257;l=d(M[g])+P[g];g=K[d(5)]>>3;8g;g++)R[g]=0;for(g=0;gdistanceTree");for(g=0;g"+U[g].b0+" "+U[g].b1+" "+U[g].jump+" "+U[g].jumppos)}l=h+A;y=0;var q= --1;for(m&&document.write("
n="+l+" bits: "+ca+"
");y"+q+" i:"+y+" decode: "+g+" bits "+ca+"
"),16>g)R[y++]=g;else if(16==g){var o;g=3+d(2);if(y+g>l)return r=0,1;for(o=y?R[y-1]:0;g--;)R[y++]=o}else{g=17==g?3+d(3):11+d(7);if(y+g>l)return r=0,1;for(;g--;)R[y++]=0}l=da.length;for(y=0;yliteralTree");;)if(g= -j(da),256<=g){g-=256;if(0==g)break;g--;l=d(M[g])+P[g];g=j(U);8>2,c=(c&3)<<4|d>>4,h=(d&15)<<2|e>>6,g=e&63,isNaN(d)?h=g=64:isNaN(e)&&(g=64),b.push([this._keyStr.charAt(f),this._keyStr.charAt(c),this._keyStr.charAt(h),this._keyStr.charAt(g)].join(""));return b.join("")},decode:function(a,b){for(var c=[],d,e,f,h,g, -k=0,a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,e=(e&15)<<4|h>>2,f=(h&3)<<6|g,c.push(String.fromCharCode(d)),64!=h&&c.push(String.fromCharCode(e)),64!=g&&c.push(String.fromCharCode(f));c=c.join("");b&&(c=JXG.Util.Base64._utf8_decode(c));return c},_utf8_encode:function(a){for(var a=a.replace(/\r\n/g,"\n"),b="",c=0;cd?b+=String.fromCharCode(d):(127d?b+=String.fromCharCode(d>>6|192):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128)),b+=String.fromCharCode(d&63|128))}return b},_utf8_decode:function(a){for(var b=[],c=0,d=0,e=0,f=0;cd?(b.push(String.fromCharCode(d)),c++):191d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((d&15)<<12| -(e&63)<<6|f&63)),c+=3);return b.join("")},_destrip:function(a,b){var c=[],d,e,f=[];null==b&&(b=76);a.replace(/ /g,"");d=a.length/b;for(e=0;ed?(b.push(String.fromCharCode(d)),c++):191d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((d&15)<<12|(e&63)<<6|f&63)),c+=3);return b.join("")}; -JXG.Util.genUUID=function(){for(var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d,e=0;36>e;e++)8==e||13==e||18==e||23==e?b[e]="-":14==e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19==e?d&3|8:d]);return b.join("")}; -function openpgp_crypto_symmetricEncrypt(a,b,c,d,e){switch(b){case 0:return d;case 2:return openpgp_cfb_encrypt(a,desede,d,8,c,e).substring(0,d.length+10);case 3:return openpgp_cfb_encrypt(a,cast5_encrypt,d,8,c,e).substring(0,d.length+10);case 4:return openpgp_cfb_encrypt(a,BFencrypt,d,8,c,e).substring(0,d.length+10);case 7:case 8:case 9:return openpgp_cfb_encrypt(a,AESencrypt,d,16,keyExpansion(c),e).substring(0,d.length+18);case 10:return openpgp_cfb_encrypt(a,TFencrypt,d,16,c,e).substring(0,d.length+ -18);case 1:return util.print_error("IDEA Algorithm not implemented"),null;default:return null}} -function openpgp_crypto_symmetricDecrypt(a,b,c,d){util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nalgo:"+a+"\nencrypteddata:",c);var e=0;d||(e=2);switch(a){case 0:return c;case 2:return openpgp_cfb_decrypt(desede,8,b,c,d).substring(e,c.length+e-10);case 3:return openpgp_cfb_decrypt(cast5_encrypt,8,b,c,d).substring(e,c.length+e-10);case 4:return openpgp_cfb_decrypt(BFencrypt,8,b,c,d).substring(e,c.length+e-10);case 7:case 8:case 9:return openpgp_cfb_decrypt(AESencrypt,16,keyExpansion(b), -c,d).substring(e,c.length+e-18);case 10:return openpgp_cfb_decrypt(TFencrypt,16,b,c,d).substring(e,c.length+e-18);case 1:util.print_error(""+(1==a?"IDEA Algorithm not implemented":"Twofish Algorithm not implemented"))}return null} -function openpgp_crypto_asymetricEncrypt(a,b,c){switch(a){case 1:case 2:case 3:var a=new RSA,d=b[0].toBigInteger(),b=b[1].toBigInteger(),c=c.toBigInteger();return a.encrypt(c,b,d).toMPI();case 16:var a=new Elgamal,d=b[0].toBigInteger(),e=b[1].toBigInteger(),b=b[2].toBigInteger(),c=c.toBigInteger();return a.encrypt(c,e,d,b);default:return null}} -function openpgp_crypto_asymetricDecrypt(a,b,c,d){switch(a){case 1:case 2:case 3:var a=new RSA,e=c[0].toBigInteger(),b=c[1].toBigInteger(),f=c[2].toBigInteger(),c=c[3].toBigInteger(),d=d[0].toBigInteger();return a.decrypt(d,e,b,f,c);case 16:return a=new Elgamal,c=c[0].toBigInteger(),e=d[0].toBigInteger(),d=d[1].toBigInteger(),b=b[0].toBigInteger(),a.decrypt(e,d,b,c);default:return null}} -function openpgp_crypto_getPrefixRandom(a){switch(a){case 2:case 3:case 4:return openpgp_crypto_getRandomBytes(8);case 7:case 8:case 9:case 10:return openpgp_crypto_getRandomBytes(16);default:return null}} -function openpgp_crypto_MDCSystemBytes(a,b,c){util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nencrypteddata:",c);switch(a){case 0:return c;case 2:return openpgp_cfb_mdc(desede,8,b,c,openpgp_cfb);case 3:return openpgp_cfb_mdc(cast5_encrypt,8,b,c);case 4:return openpgp_cfb_mdc(BFencrypt,8,b,c);case 7:case 8:case 9:return openpgp_cfb_mdc(AESencrypt,16,keyExpansion(b),c);case 10:return openpgp_cfb_mdc(TFencrypt,16,b,c);case 1:util.print_error(""+(1==a?"IDEA Algorithm not implemented": -"Twofish Algorithm not implemented"))}return null}function openpgp_crypto_generateSessionKey(a){switch(a){case 2:case 8:return openpgp_crypto_getRandomBytes(24);case 3:case 4:case 7:return util.print_debug("length = 16:\n"+util.hexstrdump(openpgp_crypto_getRandomBytes(16))),openpgp_crypto_getRandomBytes(16);case 9:case 10:return openpgp_crypto_getRandomBytes(32)}return null} -function openpgp_crypto_verifySignature(a,b,c,d,e){var f=openpgp_crypto_hashData(b,e);switch(a){case 1:case 2:case 3:e=new RSA;a=d[0].toBigInteger();d=d[1].toBigInteger();c=c[0].toBigInteger();d=e.verify(c,d,a);b=openpgp_encoding_emsa_pkcs1_decode(b,d.toMPI().substring(2));return-1==b?(util.print_error("PKCS1 padding in message or key incorrect. Aborting..."),!1):b==f;case 16:return util.print_error("signing with Elgamal is not defined in the OpenPGP standard."),null;case 17:var a=new DSA,f=c[0].toBigInteger(), -c=c[1].toBigInteger(),h=d[0].toBigInteger(),g=d[1].toBigInteger(),k=d[2].toBigInteger(),d=d[3].toBigInteger(),d=a.verify(b,f,c,e,h,g,k,d);return 0==d.compareTo(f);default:return null}} -function openpgp_crypto_signData(a,b,c,d,e){switch(b){case 1:case 2:case 3:var b=new RSA,d=d[0].toBigInteger(),f=c[0].toBigInteger(),a=openpgp_encoding_emsa_pkcs1_encode(a,e,c[0].mpiByteLength);util.print_debug("signing using RSA");return b.sign(a,d,f).toMPI();case 17:b=new DSA;util.print_debug("DSA Sign: q size in Bytes:"+c[1].getByteLength());var f=c[0].toBigInteger(),h=c[1].toBigInteger(),g=c[2].toBigInteger();c[3].toBigInteger();c=d[0].toBigInteger();a=b.sign(a,e,g,f,h,c);util.print_debug("signing using DSA\n result:"+ -util.hexstrdump(a[0])+"|"+util.hexstrdump(a[1]));return a[0]+a[1];case 16:return util.print_debug("signing with Elgamal is not defined in the OpenPGP standard."),null;default:return null}}function openpgp_crypto_hashData(a,b){var c=null;switch(a){case 1:c=MD5(b);break;case 2:c=str_sha1(b);break;case 3:c=RMDstring(b);break;case 8:c=str_sha256(b);break;case 9:c=str_sha384(b);break;case 10:c=str_sha512(b);break;case 11:c=str_sha224(b)}return c} -function openpgp_crypto_getHashByteLength(a){switch(a){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28}return null}function openpgp_crypto_getRandomBytes(a){for(var b="",c=0;cb-a;)window.crypto.getRandomValues(c);return a+Math.abs(c[0]&Math.pow(2,d)-1)}function openpgp_crypto_getSecureRandomOctet(){var a=new Uint32Array(1);window.crypto.getRandomValues(a);return a[0]&255} -function openpgp_crypto_getRandomBigInteger(a){if(0>a)return null;var b=openpgp_crypto_getRandomBytes(Math.floor((a+7)/8));0=b.compareTo(a))){for(var c=b.subtract(a),d=openpgp_crypto_getRandomBigInteger(c.bitLength());d>c;)d=openpgp_crypto_getRandomBigInteger(c.bitLength());return a.add(d)}} -function openpgp_crypto_testRSA(a){debugger;var b=new RSA,c=new openpgp_type_mpi;c.create(openpgp_encoding_eme_pkcs1_encode("ABABABAB",128));c=b.encrypt(c.toBigInteger(),a.ee,a.n);b.decrypt(c,a.d,a.p,a.q,a.u)} -function openpgp_crypto_generateKeyPair(a,b,c,d,e){var f,h,g=new Date,g=g.getTime()/1E3,g=String.fromCharCode(Math.floor(g/16777216%256))+String.fromCharCode(Math.floor(g/65536%256))+String.fromCharCode(Math.floor(g/256%256))+String.fromCharCode(Math.floor(g%256));switch(a){case 1:b=(new RSA).generate(b,"10001");f=(new openpgp_packet_keymaterial).write_private_key(a,b,c,d,e,g);h=(new openpgp_packet_keymaterial).write_public_key(a,b,g);break;default:util.print_error("Unknown keytype "+a)}return{privateKey:f, -publicKey:h}}var dbits,canary=244837814094590,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}function am1(a,b,c,d,e,f){for(;0<=--f;){var h=b*this[a++]+c[d]+e,e=Math.floor(h/67108864);c[d++]=h&67108863}return e} -function am2(a,b,c,d,e,f){for(var h=b&32767,b=b>>15;0<=--f;){var g=this[a]&32767,k=this[a++]>>15,j=b*g+k*h,g=h*g+((j&32767)<<15)+c[d]+(e&1073741823),e=(g>>>30)+(j>>>15)+b*k+(e>>>30);c[d++]=g&1073741823}return e}function am3(a,b,c,d,e,f){for(var h=b&16383,b=b>>14;0<=--f;){var g=this[a]&16383,k=this[a++]>>14,j=b*g+k*h,g=h*g+((j&16383)<<14)+c[d]+e,e=(g>>28)+(j>>14)+b*k;c[d++]=g&268435455}return e} -j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return null==c?-1:c}function bnpCopyTo(a){for(var b=this.t-1;0<=b;--b)a[b]=this[b];a.t=this.t;a.s=this.s}function bnpFromInt(a){this.t=1;this.s=0>a?-1:0;0a?this[0]=a+DV:this.t=0}function nbv(a){var b=nbi();b.fromInt(a);return b} -function bnpFromString(a,b){var c;if(16==b)c=4;else if(8==b)c=3;else if(256==b)c=8;else if(2==b)c=1;else if(32==b)c=5;else if(4==b)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var d=a.length,e=!1,f=0;0<=--d;){var h=8==c?a[d]&255:intAt(a,d);0>h?"-"==a.charAt(d)&&(e=!0):(e=!1,0==f?this[this.t++]=h:f+c>this.DB?(this[this.t-1]|=(h&(1<>this.DB-f):this[this.t-1]|=h<=this.DB&&(f-=this.DB))}if(8==c&&0!=(a[0]&128))this.s=-1,0this.s)return"-"+this.negate().toString(a);if(16==a)a=4;else if(8==a)a=3;else if(2==a)a=1;else if(32==a)a=5;else if(4==a)a=2;else return this.toRadix(a);var b=(1<>h))d=!0,e=int2char(c);for(;0<=f;)h>(h+=this.DB-a)):(c=this[f]>>(h-=a)&b,0>=h&&(h+=this.DB,--f)),0this.s?this.negate():this}function bnCompareTo(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t,b=c-a.t;if(0!=b)return b;for(;0<=--c;)if(0!=(b=this[c]-a[c]))return b;return 0}function nbits(a){var b=1,c;if(0!=(c=a>>>16))a=c,b+=16;if(0!=(c=a>>8))a=c,b+=8;if(0!=(c=a>>4))a=c,b+=4;if(0!=(c=a>>2))a=c,b+=2;0!=a>>1&&(b+=1);return b} -function bnBitLength(){return 0>=this.t?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(a,b){var c;for(c=this.t-1;0<=c;--c)b[c+a]=this[c];for(c=a-1;0<=c;--c)b[c]=0;b.t=this.t+a;b.s=this.s}function bnpDRShiftTo(a,b){for(var c=a;c>d|h,h=(this[g]&e)<=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,f=(1<>d;for(var h=c+1;h>d;0>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b[c++]=this.DV+d:0=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}0=d.t)){var e=this.abs();if(e.t>this.F2:0),j=this.FV/k,k=(1<h&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);0>this.s&&0a.s||0<=a.compareTo(this.m)?a.mod(this.m):a}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}function cSqrTo(a,b){a.squareTo(b);this.reduce(b)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo; -function bnpInvDigit(){if(1>this.t)return 0;var a=this[0];if(0==(a&1))return 0;var b=a&3,b=b*(2-(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return 0>15;this.um=(1<a.s&&0>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp();a.drShiftTo(this.m.t,a);0<=a.compareTo(this.m)&&a.subTo(this.m,a)}function montSqrTo(a,b){a.squareTo(b);this.reduce(b)}function montMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Montgomery.prototype.convert=montConvert; -Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return 0==(0a)return BigInteger.ONE;var c=nbi(),d=nbi(),e=b.convert(this),f=nbits(a)-1;for(e.copyTo(c);0<=--f;)if(b.sqrTo(c,d),0<(a&1<a||b.isEven()?new Classic(b):new Montgomery(b);return this.exp(a,c)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo; -BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt; -BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function SecureRandom(){this.nextBytes=function(a){for(var b=0;b>1;d.e=parseInt(c,16);for(d.ee=new BigInteger(c,16);;){for(;!(d.p=new BigInteger(b-f,1,e),0==d.p.subtract(BigInteger.ONE).gcd(d.ee).compareTo(BigInteger.ONE)&&d.p.isProbablePrime(10)););for(;!(d.q=new BigInteger(f,1,e),0==d.q.subtract(BigInteger.ONE).gcd(d.ee).compareTo(BigInteger.ONE)&&d.q.isProbablePrime(10));); -if(0>=d.p.compareTo(d.q)){var h=d.p;d.p=d.q;d.q=h}var h=d.p.subtract(BigInteger.ONE),g=d.q.subtract(BigInteger.ONE),k=h.multiply(g);if(0==k.gcd(d.ee).compareTo(BigInteger.ONE)){d.n=d.p.multiply(d.q);d.d=d.ee.modInverse(k);d.dmp1=d.d.mod(h);d.dmq1=d.d.mod(g);d.u=d.p.modInverse(d.q);break}}return d};this.keyObject=a}function bnClone(){var a=nbi();this.copyTo(a);return a} -function bnIntValue(){if(0>this.s){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function bnShortValue(){return 0==this.t?this.s:this[0]<<16>>16}function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function bnSigNum(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1} -function bnpToRadix(a){null==a&&(a=10);if(0==this.signum()||2>a||36k?"-"==a.charAt(g)&&0==this.signum()&&(e=!0):(h=b*h+k,++f>=c&&(this.dMultiply(d),this.dAddOffset(h,0),h=f=0))}0a)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(BigInteger.ONE.shiftLeft(a-1),this)}else{var c=[],d=a&7;c.length=(a>>3)+1;b.nextBytes(c);c[0]=0>c)!=(this.s&this.DM)>>c)b[e++]=d|this.s<c?(d=(this[a]&(1<>(c+=this.DB-8)):(d=this[a]>>(c-=8)&255,0>=c&&(c+=this.DB,--a)),0this.compareTo(a)?this:a}function bnMax(a){return 0a?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b}function bnShiftRight(a){var b=nbi();0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b} -function lbit(a){if(0==a)return-1;var b=0;0==(a&65535)&&(a>>=16,b+=16);0==(a&255)&&(a>>=8,b+=8);0==(a&15)&&(a>>=4,b+=4);0==(a&3)&&(a>>=2,b+=2);0==(a&1)&&++b;return b}function bnGetLowestSetBit(){for(var a=0;athis.s?this.t*this.DB:-1}function cbit(a){for(var b=0;0!=a;)a&=a-1,++b;return b}function bnBitCount(){for(var a=0,b=this.s&this.DM,c=0;c=this.t?0!=this.s:0!=(this[b]&1<>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=a.s}b.s=0>d?-1:0;0d&&(b[c++]=this.DV+d);b.t=c;b.clamp()}function bnAdd(a){var b=nbi();this.addTo(a,b);return b}function bnSubtract(a){var b=nbi();this.subTo(a,b);return b} -function bnMultiply(a){var b=nbi();this.multiplyTo(a,b);return b}function bnSquare(){var a=nbi();this.squareTo(a);return a}function bnDivide(a){var b=nbi();this.divRemTo(a,b,null);return b}function bnRemainder(a){var b=nbi();this.divRemTo(a,null,b);return b}function bnDivideAndRemainder(a){var b=nbi(),c=nbi();this.divRemTo(a,b,c);return[b,c]}function bnpDMultiply(a){this[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()} -function bnpDAddOffset(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function NullExp(){}function nNop(a){return a}function nMulTo(a,b,c){a.multiplyTo(b,c)}function nSqrTo(a,b){a.squareTo(b)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(a){return this.exp(a,new NullExp)} -function bnpMultiplyLowerTo(a,b,c){var d=Math.min(this.t+a.t,b);c.s=0;for(c.t=d;0a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;var b=nbi();a.copyTo(b);this.reduce(b);return b}function barrettRevert(a){return a} -function barrettReduce(a){a.drShiftTo(this.m.t-1,this.r2);if(a.t>this.m.t+1)a.t=this.m.t+1,a.clamp();this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert; -Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo; -function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var h=[],g=3,k=d-1,j=(1<=k?o=a[l]>>c-k&j:(o=(a[l]&(1<>this.DB+c-k));for(g=d;0==(o&1);)o>>=1,--g;if(0>(c-=g))c+=this.DB,--l;if(s)h[o].copyTo(e), -s=!1;else{for(;1--c&&(c=this.DB-1,--l)}return f.revert(e)} -function bnGCD(a){var b=0>this.s?this.negate():this.clone(),a=0>a.s?a.negate():a.clone();if(0>b.compareTo(a))var c=b,b=a,a=c;var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(0>d)return b;c=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0g.signum())g.addTo(a,g);else return g;return 0>g.signum()?g.add(a):g} -var lowprimes=[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,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727, -733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],lplim=67108864/lowprimes[lowprimes.length-1]; -function bnIsProbablePrime(a){var b,c=this.abs();if(1==c.t&&c[0]<=lowprimes[lowprimes.length-1]){for(b=0;b>>16))a=c,b+=16;if(0!=(c=a>>8))a=c,b+=8;if(0!=(c=a>>4))a=c,b+=4;if(0!=(c=a>>2))a=c,b+=2;0!=a>>1&&(b+=1);return b}function bnToMPI(){var a=this.toByteArray(),b=8*(a.length-1)+nbits(a[0]),c;c=""+String.fromCharCode((b&65280)>>8);c+=String.fromCharCode(b&255);return c+=util.bin2str(a)} -function bnpMillerRabin(a){var b=this.subtract(BigInteger.ONE),c=b.getLowestSetBit();if(0>=c)return!1;var d=b.shiftRight(c),a=a+1>>1;if(a>lowprimes.length)a=lowprimes.length;for(var e=nbi(),f=0;fb?2:b;case 28:return 11b?11:b;case 32:return 10b?8:b;default:return util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}};this.sign=function(a,b,c,d,e,f){a=util.getLeftNBits(openpgp_crypto_hashData(a,b),e.bitLength());a=new BigInteger(util.hexstrdump(a),16);b=openpgp_crypto_getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), -e.subtract(BigInteger.ONE));c=c.modPow(b,d).mod(e);e=b.modInverse(e).multiply(a.add(f.multiply(c))).mod(e);f=[];f[0]=c.toMPI();f[1]=e.toMPI();return f};this.verify=function(a,b,c,d,e,f,h,g){a=util.getLeftNBits(openpgp_crypto_hashData(a,d),f.bitLength());a=new BigInteger(util.hexstrdump(a),16);if(0this.certificationSignatures[a].creationTime){var e=String.fromCharCode(153)+b.header.substring(1)+b.data+String.fromCharCode(180)+String.fromCharCode(this.text.length>>24&255)+String.fromCharCode(this.text.length>>16&255)+String.fromCharCode(this.text.length>>8&255)+String.fromCharCode(this.text.length&255)+this.text;if(d.verify(e,c)){result[a]=this.certificationSignatures[a].issuerKeyId==b.getKeyId()?6:3;continue}}e=String.fromCharCode(153)+b.header.substring(1)+b.data+String.fromCharCode(180)+ +String.fromCharCode(this.text.length>>24&255)+String.fromCharCode(this.text.length>>16&255)+String.fromCharCode(this.text.length>>8&255)+String.fromCharCode(this.text.length&255)+this.text;result[a]=this.certificationSignatures[a].verify(e,c)?4:0}}else if(3==this.certificationSignatures[a].version)if(null==this.certificationSignatures[a].keyId)result[a]=0;else if(c=openpgp.keyring.getPublicKeysForKeyId(this.certificationSignatures[a].keyId),null==c||0==c.length)result[a]=2;else if(c=publicKey.obj.getSigningKey(), +null==c)result[a]=0;else{d=this.hasCertificationRevocationSignature(this.certificationSignatures[a].keyId);if(null!=d&&d.creationTime>this.certificationSignatures[a].creationTime&&(e=String.fromCharCode(153)+this.publicKeyPacket.header.substring(1)+this.publicKeyPacket.data+this.text,d.verify(e,c))){result[a]=d.keyId==b.getKeyId()?6:3;continue}e=String.fromCharCode(153)+b.header.substring(1)+b.data+this.text;result[a]=this.certificationSignatures[a].verify(e,c)?4:0}else result[a]=0;return result}; +this.verify=function(b){b=this.verifyCertificationSignatures(b);return-1!=b.indexOf(6)?2:-1!=b.indexOf(5)?1:0};this.read_packet=function(b,a,c){this.text="";this.packetLength=c;for(var d=0;dg.signatureType){this.certificationSignatures[this.certificationSignatures.length]=g;break}else if(48==g.signatureType){this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=g;break}else if(24==g.signatureType){this.certificationSignatures[this.certificationSignatures.length]=g;break}else util.debug("unknown sig t: "+g.signatureType+"@"+(e-(g.packetLength+g.headerLength))); +default:return this.data=a,this.position=c-b.packetLength,this.len=e-c-(g.headerLength+g.packetLength)}}this.data=a;this.position=c-b.packetLength;return this.len=e-c-(g.headerLength+g.packetLength)}if(5==b.tagType){this.parentNode=b;for(e=c;a.length!=e;)if(g=openpgp_packet.read_packet(a,e,f-(e-c)),null==g){util.print_error("parsing ends here @:"+e+" l:"+f);break}else switch(e+=g.packetLength+g.headerLength,g.tagType){case 2:15g.signatureType?this.certificationSignatures[this.certificationSignatures.length]= +g:48==g.signatureType&&(this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=g);default:return this.data=a,this.position=c-b.packetLength,this.len=e-c-(g.headerLength+g.packetLength)}}else util.print_error("unknown parent node for a userId packet "+b.tagType)}} +function openpgp_packet_encryptedsessionkey(){this.read_pub_key_packet=function(b,a,c){this.tagType=1;this.packetLength=c;var d=a;if(10>c)return util.print_error("openpgp.packet.encryptedsessionkey.js\ninvalid length"),null;this.version=b[d++].charCodeAt();this.keyId=new openpgp_type_keyid;this.keyId.read_packet(b,d);d+=8;this.publicKeyAlgorithmUsed=b[d++].charCodeAt();switch(this.publicKeyAlgorithmUsed){case 1:case 2:this.MPIs=[];this.MPIs[0]=new openpgp_type_mpi;this.MPIs[0].read(b,d,d-a);break; +case 16:this.MPIs=[];this.MPIs[0]=new openpgp_type_mpi;this.MPIs[0].read(b,d,d-a);d+=this.MPIs[0].packetLength;this.MPIs[1]=new openpgp_type_mpi;this.MPIs[1].read(b,d,d-a);break;default:util.print_error("openpgp.packet.encryptedsessionkey.js\nunknown public key packet algorithm type "+this.publicKeyAlgorithmType)}return this};this.read_symmetric_key_packet=function(b,a,c){this.tagType=3;var d=a;this.version=b[d++];this.symmetricKeyAlgorithmUsed=b[d++];this.s2k=new openpgp_type_s2k;this.s2k.read(b, +d);if(s2k.s2kLength+d>8&255),d=d+String.fromCharCode(e&255),f=f+b+String.fromCharCode(c),b=new openpgp_type_mpi,a=openpgp_crypto_asymetricEncrypt(c,a,b.create(openpgp_encoding_eme_pkcs1_encode(d,a[0].mpiByteLength))),c=0;c>24&255),a=a+String.fromCharCode(Math.round(this.date.getTime()/1E3)>>16&255),a=a+String.fromCharCode(Math.round(this.date.getTime()/ +1E3)>>8&255),a=a+String.fromCharCode(Math.round(this.date.getTime()/1E3)&255);this.data=b;return a+b}} +function openpgp_packet_encrypteddata(){this.tagType=9;this.decryptedData=this.encryptedData=this.packetLength=null;this.decrypt_sym=function(b,a){this.decryptedData=openpgp_crypto_symmetricDecrypt(b,a,this.encryptedData,!0);util.print_debug("openpgp.packet.encryptedintegrityprotecteddata.js\ndata: "+util.hexstrdump(this.decryptedData));return this.decryptedData};this.toString=function(){return"5.7. Symmetrically Encrypted Data Packet (Tag 9)\n length: "+this.packetLength+"\n Used symmetric algorithm: "+ +this.algorithmType+"\n encrypted data: Bytes ["+util.hexstrdump(this.encryptedData)+"]\n"};this.read_packet=function(b,a,c){this.packetLength=c;this.encryptedData=b.substring(a,a+c);return this};this.write_packet=function(b,a,c){b=""+openpgp_crypto_symmetricEncrypt(openpgp_crypto_getPrefixRandom(b),b,a,c,!0);return b=openpgp_packet.write_packet_header(9,b.length)+b}} +function openpgp_packet_userattribute(){this.tagType=17;this.certificationSignatures=[];this.certificationRevocationSignatures=[];this.revocationSignatures=[];this.parentNode=null;this.read_packet=function(b,a,c){var d=0;this.packetLength=c;this.userattributes=[];for(var e=a;c!=d;){var f=0;192>b[e].charCodeAt()?(packet_length=b[e++].charCodeAt(),f=1):192<=b[e].charCodeAt()&&224>b[e].charCodeAt()?(packet_length=(b[e++].charCodeAt()-192<<8)+b[e++].charCodeAt()+192,f=2):223b[e].charCodeAt()? +(packet_length=1<<(b[e++].charCodeAt()&31),f=1):(f=5,e++,packet_length=b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt());b[e++].charCodeAt();packet_length--;f++;this.userattributes[0]=[];this.userattributes[0]=b.substring(e,e+packet_length);e+=packet_length;d+=f+packet_length}this.packetLength=e-a;return this};this.read_nodes=function(b,a,c,d){this.parentNode=b;for(var e=c,f=d;a.length!=e;){var g=openpgp_packet.read_packet(a,e,f);if(null==g){util.print_error("openpgp.packet.userattribute.js\n[user_attr] parsing ends here @:"+ +e+" l:"+f);break}else switch(g.tagType){case 2:15g.signatureType?this.certificationSignatures[this.certificationSignatures.length]=g:32==g.signatureType&&(this.certificationRevocationSignatures[this.certificationRevocationSignatures.length]=g);e+=g.packetLength+g.headerLength;f=d-(e-c);break;default:return this.data=a,this.position=c-b.packetLength,this.len=e-c}}this.data=a;this.position=c-b.packetLength;return this.len=e-c};this.toString=function(){for(var b="5.12. User Attribute Packet (Tag 17)\n AttributePackets: (count = "+ +this.userattributes.length+")\n",a=0;aa?result+=String.fromCharCode(a):191a?(result+=String.fromCharCode((a-192>>8)+192),result+=String.fromCharCode(a-192&255)):(result+=String.fromCharCode(255),result+=String.fromCharCode(a>>24&255),result+=String.fromCharCode(a>>16&255),result+=String.fromCharCode(a>>8&255),result+=String.fromCharCode(a&255));return result}this.encode_length=b;this.write_old_packet_header=function(a,b){var d="";256>b?(d+=String.fromCharCode(128|a<<2),d+= +String.fromCharCode(b)):(65536>b?(d+=String.fromCharCode(a<<2|129),d+=String.fromCharCode(b>>8)):(d+=String.fromCharCode(a<<2|130),d+=String.fromCharCode(b>>24&255),d+=String.fromCharCode(b>>16&255),d+=String.fromCharCode(b>>8&255)),d+=String.fromCharCode(b&255));return d};this.write_packet_header=function(a,c){var d;d=""+String.fromCharCode(192|a);return d+=b(c)};this.read_packet=function(a,b){if(null==a||a.length<=b||2>a.substring(b).length||0==(a[b].charCodeAt()&128))return util.print_error("Error during parsing. This message / key is propably not containing a valid OpenPGP format."), +null;var d=b,e=-1,f=-1,f=0;0!=(a[d].charCodeAt()&64)&&(f=1);var g;f?e=a[d].charCodeAt()&63:(e=(a[d].charCodeAt()&63)>>2,g=a[d].charCodeAt()&3);d++;var h=null,k=-1;if(f)if(192>a[d].charCodeAt())packet_length=a[d++].charCodeAt(),util.print_debug("1 byte length:"+packet_length);else if(192<=a[d].charCodeAt()&&224>a[d].charCodeAt())packet_length=(a[d++].charCodeAt()-192<<8)+a[d++].charCodeAt()+192,util.print_debug("2 byte length:"+packet_length);else if(223a[d].charCodeAt()){packet_length= +1<<(a[d++].charCodeAt()&31);util.print_debug("4 byte length:"+packet_length);k=d+packet_length;for(h=a.substring(d,d+packet_length);;)if(192>a[k].charCodeAt()){f=a[k++].charCodeAt();packet_length+=f;h+=a.substring(k,k+f);k+=f;break}else if(192<=a[k].charCodeAt()&&224>a[k].charCodeAt()){f=(a[k++].charCodeAt()-192<<8)+a[k++].charCodeAt()+192;packet_length+=f;h+=a.substring(k,k+f);k+=f;break}else if(223a[k].charCodeAt())f=1<<(a[k++].charCodeAt()&31),packet_length+=f,h+=a.substring(k, +k+f),k+=f;else{k++;f=a[k++].charCodeAt()<<24|a[k++].charCodeAt()<<16|a[k++].charCodeAt()<<8|a[k++].charCodeAt();h+=a.substring(k,k+f);packet_length+=f;k+=f;break}}else d++,packet_length=a[d++].charCodeAt()<<24|a[d++].charCodeAt()<<16|a[d++].charCodeAt()<<8|a[d++].charCodeAt();else switch(g){case 0:packet_length=a[d++].charCodeAt();break;case 1:packet_length=a[d++].charCodeAt()<<8|a[d++].charCodeAt();break;case 2:packet_length=a[d++].charCodeAt()<<24|a[d++].charCodeAt()<<16|a[d++].charCodeAt()<<8| +a[d++].charCodeAt()}-1==k&&(k=packet_length);null==h&&(h=a.substring(d,d+k));switch(e){case 0:break;case 1:e=new openpgp_packet_encryptedsessionkey;if(null!=e.read_pub_key_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 2:e=new openpgp_packet_signature;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 3:e=new openpgp_packet_encryptedsessionkey;if(null!=e.read_symmetric_key_packet(h,0,packet_length))return e.headerLength= +d-b,e.packetLength=k,e;break;case 4:e=new openpgp_packet_onepasssignature;if(e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 5:e=new openpgp_packet_keymaterial;e.header=a.substring(b,d);if(null!=e.read_tag5(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 6:e=new openpgp_packet_keymaterial;e.header=a.substring(b,d);if(null!=e.read_tag6(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 7:e=new openpgp_packet_keymaterial; +if(null!=e.read_tag7(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 8:e=new openpgp_packet_compressed;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 9:e=new openpgp_packet_encrypteddata;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 10:e=new openpgp_packet_marker;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 11:e=new openpgp_packet_literaldata; +if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.header=a.substring(b,d),e.packetLength=k,e;break;case 12:break;case 13:e=new openpgp_packet_userid;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 14:e=new openpgp_packet_keymaterial;e.header=a.substring(b,d);if(null!=e.read_tag14(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 17:e=new openpgp_packet_userattribute;if(null!=e.read_packet(h,0,packet_length))return e.headerLength= +d-b,e.packetLength=k,e;break;case 18:e=new openpgp_packet_encryptedintegrityprotecteddata;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;case 19:e=new openpgp_packet_modificationdetectioncode;if(null!=e.read_packet(h,0,packet_length))return e.headerLength=d-b,e.packetLength=k,e;break;default:return util.print_error("openpgp.packet.js\n[ERROR] openpgp_packet: failed to parse packet @:"+d+"\nchar:'"+util.hexstrdump(a.substring(d))+"'\ninput:"+util.hexstrdump(a)), +null}}}var openpgp_packet=new _openpgp_packet; +function openpgp_packet_compressed(){this.tagType=8;this.read_packet=function(b,a,c){this.packetLength=c;var d=a;this.type=b.charCodeAt(d++);this.compressedData=b.substring(a+1,a+c);return this};this.toString=function(){return"5.6. Compressed Data Packet (Tag 8)\n length: "+this.packetLength+"\n Compression Algorithm = "+this.type+"\n Compressed Data: Byte ["+util.hexstrdump(this.compressedData)+"]\n"};this.compress=function(b,a){this.type=b;this.decompressedData=a;switch(this.type){case 0:this.compressedData= +this.decompressedData;break;case 1:util.print_error("Compression algorithm ZIP [RFC1951] is not implemented.");break;case 2:util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented.");break;case 3:util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}this.packetLength=this.compressedData.length+1;return this.compressedData};this.decompress=function(){if(null!=this.decompressedData)return this.decompressedData; +if(null==this.type)return null;switch(this.type){case 0:this.decompressedData=this.compressedData;break;case 1:var b=this.compressedData,b=s2r(b).replace(/\n/g,""),b=new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(b)),b=unescape(b.deflate()[0][0]),b=openpgp_packet.read_packet(b,0,b.length);util.print_info("Decompressed packet [Type 1-ZIP]: "+b);this.decompressedData=b.data;break;case 2:8==this.compressedData.charCodeAt(0)%16?(b=this.compressedData.substring(0,this.compressedData.length-4),b=s2r(b).replace(/\n/g, +""),b=JXG.decompress(b),b=openpgp_packet.read_packet(b,0,b.length),util.print_info("Decompressed packet [Type 2-ZLIB]: "+b),this.decompressedData=b.data):util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method.");break;case 3:util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}util.print_debug("decompressed:"+util.hexstrdump(this.decompressedData));return this.decompressedData}; +this.write_packet=function(b,a){this.decompressedData=a;if(null==b)this.type=1;var c=String.fromCharCode(this.type)+this.compress(this.type);return openpgp_packet.write_packet_header(8,c.length)+c}} +function openpgp_packet_keymaterial(){this.subKeyRevocationSignature=this.subKeySignature=this.parentNode=this.checksum=this.hasUnencryptedSecretKeyData=this.encryptedMPIData=this.IVLength=this.s2kUsageConventions=this.symmetricEncryptionAlgorithm=this.publicKey=this.secMPIs=this.MPIs=this.expiration=this.version=this.creationTime=this.tagType=this.publicKeyAlgorithm=null;this.read_tag5=function(b,a,c){this.tagType=5;this.read_priv_key(b,a,c);return this};this.read_tag6=function(b,a,c){this.tagType= +6;this.packetLength=c;this.read_pub_key(b,a,c);return this};this.read_tag7=function(b,a,c){this.tagType=7;this.packetLength=c;return this.read_priv_key(b,a,c)};this.read_tag14=function(b,a,c){this.subKeySignature=null;this.subKeyRevocationSignature=[];this.tagType=14;this.packetLength=c;this.read_pub_key(b,a,c);return this};this.toString=function(){var b="";switch(this.tagType){case 6:b+="5.5.1.1. Public-Key Packet (Tag 6)\n length: "+this.packetLength+"\n version: "+ +this.version+"\n creation time: "+this.creationTime+"\n expiration time: "+this.expiration+"\n publicKeyAlgorithm: "+this.publicKeyAlgorithm+"\n";break;case 14:b+="5.5.1.2. Public-Subkey Packet (Tag 14)\n length: "+this.packetLength+"\n version: "+this.version+"\n creation time: "+this.creationTime+"\n expiration time: "+this.expiration+"\n publicKeyAlgorithm: "+this.publicKeyAlgorithm+"\n";break;case 5:b+="5.5.1.3. Secret-Key Packet (Tag 5)\n length: "+ +this.packetLength+"\n version: "+this.publicKey.version+"\n creation time: "+this.publicKey.creationTime+"\n expiration time: "+this.publicKey.expiration+"\n publicKeyAlgorithm: "+this.publicKey.publicKeyAlgorithm+"\n";break;case 7:b+="5.5.1.4. Secret-Subkey Packet (Tag 7)\n length: "+this.packetLength+"\n version[1]: "+(4==this.version)+"\n creationtime[4]: "+this.creationTime+"\n expiration[2]: "+this.expiration+"\n publicKeyAlgorithm: "+ +this.publicKeyAlgorithm+"\n";break;default:b+="unknown key material packet\n"}if(null!=this.MPIs)for(var b=b+"Public Key MPIs:\n",a=0;athis.publicKeyAlgorithm?d=2:16==this.publicKeyAlgorithm?d=3:17==this.publicKeyAlgorithm&&(d=4);this.MPIs=[];for(var e=0;ethis.publicKeyAlgorithm?d=2:16==this.publicKeyAlgorithm?d=3:17==this.publicKeyAlgorithm&&(d=4);this.MPIs=[];for(e=0;ethis.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(b, +d,c-2-(d-a)),d+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(b,d,c-2-(d-a)),d+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(b,d,c-2-(d-a)),d+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(b,d,c-2-(d-a)),d+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(b,d,c-2-(d-a)),d+=this.secMPIs[0].packetLength; +else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(b,d,c-2-(d-a)),d+=this.secMPIs[0].packetLength;this.checksum=[];this.checksum[0]=b[d++].charCodeAt();this.checksum[1]=b[d++].charCodeAt()}else this.encryptedMPIData=b.substring(d,c);return this};this.decryptSecretMPIs=function(b){if(this.hasUnencryptedSecretKeyData)return this.secMPIs;var a=this.s2k.produce_key(b),c="";switch(this.symmetricEncryptionAlgorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"), +!1;case 2:c=normal_cfb_decrypt(function(a,b){return des(b,a,1,null,0)},this.IVLength,a,this.encryptedMPIData,this.IV);break;case 3:c=normal_cfb_decrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(a.substring(0,16)),this.encryptedMPIData,this.IV);break;case 4:c=normal_cfb_decrypt(function(a,b){return(new Blowfish(b)).encrypt(a)},this.IVLength,a,this.encryptedMPIData,this.IV);break;case 7:case 8:case 9:c=16;8==this.symmetricEncryptionAlgorithm&& +(c=24,a=this.s2k.produce_key(b,c));9==this.symmetricEncryptionAlgorithm&&(c=32,a=this.s2k.produce_key(b,c));c=normal_cfb_decrypt(function(a,b){return AESencrypt(util.str2bin(a),b)},this.IVLength,keyExpansion(a.substring(0,c)),this.encryptedMPIData,this.IV);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm), +!1}if(null==c)return util.print_error("openpgp.packet.keymaterial.js\ncleartextMPIs was null"),!1;b=c.length;if(254==this.s2kUsageConventions&&str_sha1(c.substring(0,c.length-20))==c.substring(c.length-20))b-=20;else if(254!=this.s2kUsageConventions&&util.calc_checksum(c.substring(0,c.length-2))==(c.charCodeAt(c.length-2)<<8|c.charCodeAt(c.length-1)))b-=2;else return!1;if(0this.publicKey.publicKeyAlgorithm)a=0,this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi, +this.secMPIs[0].read(c,0,b),a+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(c,a,b-a),a+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(c,a,b-a),a+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(c,a,b-a),a+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,c);else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs= +[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,b);return!0};this.read_nodes=function(b,a,c,d){this.parentNode=b;if(14==this.tagType){for(var b=c,e=null;a.length!=b;)if(d=a.length-b,e=openpgp_packet.read_packet(a,b,d),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_pub]parsing ends here @:"+b+" l:"+d);break}else switch(e.tagType){case 2:if(24==e.signatureType){this.subKeySignature=e;b+=e.packetLength+e.headerLength;break}else if(40==e.signatureType){this.subKeyRevocationSignature= +e;b+=e.packetLength+e.headerLength;break}else util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+e.toString());default:return this.data=a,this.position=c-this.parentNode.packetLength,this.len=b-c}this.data=a;this.position=c-this.parentNode.packetLength;return this.len=b-c}if(7==this.tagType){for(b=c;a.length!=b;)if(e=openpgp_packet.read_packet(a,b,d-(b-c)),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_priv] parsing ends here @:"+b);break}else switch(e.tagType){case 2:24== +e.signatureType?this.subKeySignature=e:40==e.signatureType&&(this.subKeyRevocationSignature[this.subKeyRevocationSignature]=e);b+=e.packetLength+e.headerLength;break;default:return this.data=a,this.position=c-this.parentNode.packetLength,this.len=b-c}this.data=a;this.position=c-this.parentNode.packetLength;return this.len=b-c}util.print_error("openpgp.packet.keymaterial.js\nunknown parent node for a key material packet "+b.tagType)};this.verifyKey=function(){if(14==this.tagType){if(null==this.subKeySignature)return 0; +if(4==this.subKeySignature.version&&null!=this.subKeySignature.keyNeverExpires&&!this.subKeySignature.keyNeverExpires&&new Date(1E3*this.subKeySignature.keyExpirationTime+this.creationTime.getTime())this.publicKeyAlgorithm){var b=this.MPIs[0].substring(this.MPIs[0].mpiByteLength-8);util.print_debug("openpgp.msg.publickey read_nodes:\nV3 key ID: "+ +b);return b}};this.getFingerprint=function(){if(4==this.version)return tohash=String.fromCharCode(153)+String.fromCharCode(this.packetdata.length>>8&255)+String.fromCharCode(this.packetdata.length&255)+this.packetdata,util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm),str_sha1(tohash,tohash.length);if(3==this.version&&0this.publicKeyAlgorithm)return MD5(this.MPIs[0].MPI)}; +this.write_private_key=function(b,a,c,d,e,f){this.symmetricEncryptionAlgorithm=e;e=String.fromCharCode(4);e+=f;switch(b){case 1:e+=String.fromCharCode(b);e+=a.n.toMPI();e+=a.ee.toMPI();if(c)switch(e+=String.fromCharCode(254),e+=String.fromCharCode(this.symmetricEncryptionAlgorithm),e+=String.fromCharCode(3),e+=String.fromCharCode(d),b=a.d.toMPI()+a.p.toMPI()+a.q.toMPI()+a.u.toMPI(),a=str_sha1(b),util.print_debug_hexstr_dump("write_private_key sha1: ",a),f=openpgp_crypto_getRandomBytes(8),util.print_debug_hexstr_dump("write_private_key Salt: ", +f),e=e+f+String.fromCharCode(96),util.print_debug("write_private_key c: 96"),c=(new openpgp_type_s2k).write(3,d,c,f,96),this.symmetricEncryptionAlgorithm){case 3:this.IVLength=8;this.IV=openpgp_crypto_getRandomBytes(this.IVLength);ciphertextMPIs=normal_cfb_encrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(c.substring(0,16)),b+a,this.IV);e+=this.IV+ciphertextMPIs;break;case 7:case 8:case 9:this.IVLength=16,this.IV=openpgp_crypto_getRandomBytes(this.IVLength), +ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.IVLength,c,b+a,this.IV),e+=this.IV+ciphertextMPIs}else e+=String.fromCharCode(0),e+=a.d.toMPI()+a.p.toMPI()+a.q.toMPI()+a.u.toMPI(),c=util.calc_checksum(a.d.toMPI()+a.p.toMPI()+a.q.toMPI()+a.u.toMPI()),e+=String.fromCharCode(c/256)+String.fromCharCode(c%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+c);break;default:e="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+b)}c=openpgp_packet.write_packet_header(5, +e.length);return{string:c+e,header:c,body:e}};this.write_public_key=function(b,a,c){var d=String.fromCharCode(4),d=d+c;switch(b){case 1:d+=String.fromCharCode(1);d+=a.n.toMPI();d+=a.ee.toMPI();break;default:util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+b)}b=openpgp_packet.write_packet_header(6,d.length);return{string:b+d,header:b,body:d}}}function MD5(b){b=md5(b);return util.hex2bin(b)} +function md5cycle(b,a){var c=b[0],d=b[1],e=b[2],f=b[3],c=ff(c,d,e,f,a[0],7,-680876936),f=ff(f,c,d,e,a[1],12,-389564586),e=ff(e,f,c,d,a[2],17,606105819),d=ff(d,e,f,c,a[3],22,-1044525330),c=ff(c,d,e,f,a[4],7,-176418897),f=ff(f,c,d,e,a[5],12,1200080426),e=ff(e,f,c,d,a[6],17,-1473231341),d=ff(d,e,f,c,a[7],22,-45705983),c=ff(c,d,e,f,a[8],7,1770035416),f=ff(f,c,d,e,a[9],12,-1958414417),e=ff(e,f,c,d,a[10],17,-42063),d=ff(d,e,f,c,a[11],22,-1990404162),c=ff(c,d,e,f,a[12],7,1804603682),f=ff(f,c,d,e,a[13],12, +-40341101),e=ff(e,f,c,d,a[14],17,-1502002290),d=ff(d,e,f,c,a[15],22,1236535329),c=gg(c,d,e,f,a[1],5,-165796510),f=gg(f,c,d,e,a[6],9,-1069501632),e=gg(e,f,c,d,a[11],14,643717713),d=gg(d,e,f,c,a[0],20,-373897302),c=gg(c,d,e,f,a[5],5,-701558691),f=gg(f,c,d,e,a[10],9,38016083),e=gg(e,f,c,d,a[15],14,-660478335),d=gg(d,e,f,c,a[4],20,-405537848),c=gg(c,d,e,f,a[9],5,568446438),f=gg(f,c,d,e,a[14],9,-1019803690),e=gg(e,f,c,d,a[3],14,-187363961),d=gg(d,e,f,c,a[8],20,1163531501),c=gg(c,d,e,f,a[13],5,-1444681467), +f=gg(f,c,d,e,a[2],9,-51403784),e=gg(e,f,c,d,a[7],14,1735328473),d=gg(d,e,f,c,a[12],20,-1926607734),c=hh(c,d,e,f,a[5],4,-378558),f=hh(f,c,d,e,a[8],11,-2022574463),e=hh(e,f,c,d,a[11],16,1839030562),d=hh(d,e,f,c,a[14],23,-35309556),c=hh(c,d,e,f,a[1],4,-1530992060),f=hh(f,c,d,e,a[4],11,1272893353),e=hh(e,f,c,d,a[7],16,-155497632),d=hh(d,e,f,c,a[10],23,-1094730640),c=hh(c,d,e,f,a[13],4,681279174),f=hh(f,c,d,e,a[0],11,-358537222),e=hh(e,f,c,d,a[3],16,-722521979),d=hh(d,e,f,c,a[6],23,76029189),c=hh(c,d, +e,f,a[9],4,-640364487),f=hh(f,c,d,e,a[12],11,-421815835),e=hh(e,f,c,d,a[15],16,530742520),d=hh(d,e,f,c,a[2],23,-995338651),c=ii(c,d,e,f,a[0],6,-198630844),f=ii(f,c,d,e,a[7],10,1126891415),e=ii(e,f,c,d,a[14],15,-1416354905),d=ii(d,e,f,c,a[5],21,-57434055),c=ii(c,d,e,f,a[12],6,1700485571),f=ii(f,c,d,e,a[3],10,-1894986606),e=ii(e,f,c,d,a[10],15,-1051523),d=ii(d,e,f,c,a[1],21,-2054922799),c=ii(c,d,e,f,a[8],6,1873313359),f=ii(f,c,d,e,a[15],10,-30611744),e=ii(e,f,c,d,a[6],15,-1560198380),d=ii(d,e,f,c,a[13], +21,1309151649),c=ii(c,d,e,f,a[4],6,-145523070),f=ii(f,c,d,e,a[11],10,-1120210379),e=ii(e,f,c,d,a[2],15,718787259),d=ii(d,e,f,c,a[9],21,-343485551);b[0]=add32(c,b[0]);b[1]=add32(d,b[1]);b[2]=add32(e,b[2]);b[3]=add32(f,b[3])}function cmn(b,a,c,d,e,f){a=add32(add32(a,b),add32(d,f));return add32(a<>>32-e,c)}function ff(b,a,c,d,e,f,g){return cmn(a&c|~a&d,b,a,e,f,g)}function gg(b,a,c,d,e,f,g){return cmn(a&d|c&~d,b,a,e,f,g)}function hh(b,a,c,d,e,f,g){return cmn(a^c^d,b,a,e,f,g)} +function ii(b,a,c,d,e,f,g){return cmn(c^(a|~d),b,a,e,f,g)}function md51(b){txt="";var a=b.length,c=[1732584193,-271733879,-1732584194,271733878],d;for(d=64;d<=b.length;d+=64)md5cycle(c,md5blk(b.substring(d-64,d)));var b=b.substring(d-64),e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(d=0;d>2]|=b.charCodeAt(d)<<(d%4<<3);e[d>>2]|=128<<(d%4<<3);if(55d;d++)e[d]=0}e[14]=8*a;md5cycle(c,e);return c} +function md5blk(b){var a=[],c;for(c=0;64>c;c+=4)a[c>>2]=b.charCodeAt(c)+(b.charCodeAt(c+1)<<8)+(b.charCodeAt(c+2)<<16)+(b.charCodeAt(c+3)<<24);return a}var hex_chr="0123456789abcdef".split("");function rhex(b){for(var a="",c=0;4>c;c++)a+=hex_chr[b>>8*c+4&15]+hex_chr[b>>8*c&15];return a}function hex(b){for(var a=0;a>16)+(a>>16)+(c>>16)<<16|c&65535}); +var jsSHA=function(){var b=function(a,b){this.highOrder=a;this.lowOrder=b},a=function(a){var b=[],c=8*a.length,d;for(d=0;d>5]|=(a.charCodeAt(d/8)&255)<<24-d%32;return b},c=function(a){var b=[],c=a.length,d,e;for(d=0;d>3]|=e<<24-4*(d%8)}return b},d=function(a){var b="",c=4*a.length,d,e;for(d=0;d>2]>>8*(3-d%4),b+="0123456789abcdef".charAt(e>>4&15)+"0123456789abcdef".charAt(e&15);return b},e=function(a){var b= +"",c=4*a.length,d,e,f;for(d=0;d>2]>>8*(3-d%4)&255)<<16|(a[d+1>>2]>>8*(3-(d+1)%4)&255)<<8|a[d+2>>2]>>8*(3-(d+2)%4)&255;for(e=0;4>e;e+=1)b=8*d+6*e<=32*a.length?b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>6*(3-e)&63):b+""}return b},f=function(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b},g=function(a,b){return a<>>32-b},h=function(a,b){return a>>>b|a<<32-b},k=function(a,c){return 32>=c?new b(a.highOrder>>> +c|a.lowOrder<<32-c,a.lowOrder>>>c|a.highOrder<<32-c):new b(a.lowOrder>>>c|a.highOrder<<32-c,a.highOrder>>>c|a.lowOrder<<32-c)},j=function(a,c){return 32>=c?new b(a.highOrder>>>c,a.lowOrder>>>c|a.highOrder<<32-c):new b(0,a.highOrder<<32-c)},l=function(a,b,c){return a&b^~a&c},o=function(a,c,d){return new b(a.highOrder&c.highOrder^~a.highOrder&d.highOrder,a.lowOrder&c.lowOrder^~a.lowOrder&d.lowOrder)},r=function(a,b,c){return a&b^a&c^b&c},p=function(a,c,d){return new b(a.highOrder&c.highOrder^a.highOrder& +d.highOrder^c.highOrder&d.highOrder,a.lowOrder&c.lowOrder^a.lowOrder&d.lowOrder^c.lowOrder&d.lowOrder)},m=function(a){return h(a,2)^h(a,13)^h(a,22)},y=function(a){var c=k(a,28),d=k(a,34),a=k(a,39);return new b(c.highOrder^d.highOrder^a.highOrder,c.lowOrder^d.lowOrder^a.lowOrder)},x=function(a){return h(a,6)^h(a,11)^h(a,25)},v=function(a){var c=k(a,14),d=k(a,18),a=k(a,41);return new b(c.highOrder^d.highOrder^a.highOrder,c.lowOrder^d.lowOrder^a.lowOrder)},u=function(a){return h(a,7)^h(a,18)^a>>>3}, +t=function(a){var c=k(a,1),d=k(a,8),a=j(a,7);return new b(c.highOrder^d.highOrder^a.highOrder,c.lowOrder^d.lowOrder^a.lowOrder)},E=function(a){return h(a,17)^h(a,19)^a>>>10},Q=function(a){var c=k(a,19),d=k(a,61),a=j(a,6);return new b(c.highOrder^d.highOrder^a.highOrder,c.lowOrder^d.lowOrder^a.lowOrder)},D=function(a,b){var c=(a&65535)+(b&65535);return((a>>>16)+(b>>>16)+(c>>>16)&65535)<<16|c&65535},M=function(a,b,c,d){var e=(a&65535)+(b&65535)+(c&65535)+(d&65535);return((a>>>16)+(b>>>16)+(c>>>16)+ +(d>>>16)+(e>>>16)&65535)<<16|e&65535},K=function(a,b,c,d,e){var f=(a&65535)+(b&65535)+(c&65535)+(d&65535)+(e&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16)&65535)<<16|f&65535},w=function(a,c){var d,e,f;d=(a.lowOrder&65535)+(c.lowOrder&65535);e=(a.lowOrder>>>16)+(c.lowOrder>>>16)+(d>>>16);f=(e&65535)<<16|d&65535;d=(a.highOrder&65535)+(c.highOrder&65535)+(e>>>16);e=(a.highOrder>>>16)+(c.highOrder>>>16)+(d>>>16);return new b((e&65535)<<16|d&65535,f)},z=function(a,c,d,e){var f,g, +h;f=(a.lowOrder&65535)+(c.lowOrder&65535)+(d.lowOrder&65535)+(e.lowOrder&65535);g=(a.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16);h=(g&65535)<<16|f&65535;f=(a.highOrder&65535)+(c.highOrder&65535)+(d.highOrder&65535)+(e.highOrder&65535)+(g>>>16);g=(a.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16);return new b((g&65535)<<16|f&65535,h)},T=function(a,c,d,e,f){var g,h,k;g=(a.lowOrder&65535)+(c.lowOrder&65535)+(d.lowOrder&65535)+(e.lowOrder& +65535)+(f.lowOrder&65535);h=(a.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16);k=(h&65535)<<16|g&65535;g=(a.highOrder&65535)+(c.highOrder&65535)+(d.highOrder&65535)+(e.highOrder&65535)+(f.highOrder&65535)+(h>>>16);h=(a.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16);return new b((h&65535)<<16|g&65535,k)},A=function(a,b){var c=[],d,e,f,h,k,j,l,m,p,s=[1732584193,4023233417,2562383102,271733878,3285377520], +o=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708, +2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];a[b>>5]|=128<<24-b%32;a[(b+65>>9<<4)+15]=b;p=a.length;for(l=0;lm;m+=1)c[m]= +16>m?a[m+l]:g(c[m-3]^c[m-8]^c[m-14]^c[m-16],1),j=20>m?K(g(d,5),e&f^~e&h,k,o[m],c[m]):40>m?K(g(d,5),e^f^h,k,o[m],c[m]):60>m?K(g(d,5),r(e,f,h),k,o[m],c[m]):K(g(d,5),e^f^h,k,o[m],c[m]),k=h,h=f,f=g(e,30),e=d,d=j;s[0]=D(d,s[0]);s[1]=D(e,s[1]);s[2]=D(f,s[2]);s[3]=D(h,s[3]);s[4]=D(k,s[4])}return s},B=function(a,c,d){var e,f,g,h,k,j,A,B,C,s,da,Y,L,ea,ca,O,fa,ga,ha,ia,ja,ka,la,ma,q,na,Z=[],sa;if("SHA-224"===d||"SHA-256"===d)da=64,e=(c+65>>9<<4)+15,ea=16,ca=1,q=Number,O=D,fa=M,ga=K,ha=u,ia=E,ja=m,ka=x,ma=r, +la=l,na=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804, +4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],s="SHA-224"===d?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];else if("SHA-384"===d||"SHA-512"===d)da=80,e=(c+128>>10<<5)+31,ea=32,ca=2,q=b,O=w,fa=z,ga=T,ha=t,ia=Q,ja=y,ka=v,ma= +p,la=o,na=[new q(1116352408,3609767458),new q(1899447441,602891725),new q(3049323471,3964484399),new q(3921009573,2173295548),new q(961987163,4081628472),new q(1508970993,3053834265),new q(2453635748,2937671579),new q(2870763221,3664609560),new q(3624381080,2734883394),new q(310598401,1164996542),new q(607225278,1323610764),new q(1426881987,3590304994),new q(1925078388,4068182383),new q(2162078206,991336113),new q(2614888103,633803317),new q(3248222580,3479774868),new q(3835390401,2666613458),new q(4022224774, +944711139),new q(264347078,2341262773),new q(604807628,2007800933),new q(770255983,1495990901),new q(1249150122,1856431235),new q(1555081692,3175218132),new q(1996064986,2198950837),new q(2554220882,3999719339),new q(2821834349,766784016),new q(2952996808,2566594879),new q(3210313671,3203337956),new q(3336571891,1034457026),new q(3584528711,2466948901),new q(113926993,3758326383),new q(338241895,168717936),new q(666307205,1188179964),new q(773529912,1546045734),new q(1294757372,1522805485),new q(1396182291, +2643833823),new q(1695183700,2343527390),new q(1986661051,1014477480),new q(2177026350,1206759142),new q(2456956037,344077627),new q(2730485921,1290863460),new q(2820302411,3158454273),new q(3259730800,3505952657),new q(3345764771,106217008),new q(3516065817,3606008344),new q(3600352804,1432725776),new q(4094571909,1467031594),new q(275423344,851169720),new q(430227734,3100823752),new q(506948616,1363258195),new q(659060556,3750685593),new q(883997877,3785050280),new q(958139571,3318307427),new q(1322822218, +3812723403),new q(1537002063,2003034995),new q(1747873779,3602036899),new q(1955562222,1575990012),new q(2024104815,1125592928),new q(2227730452,2716904306),new q(2361852424,442776044),new q(2428436474,593698344),new q(2756734187,3733110249),new q(3204031479,2999351573),new q(3329325298,3815920427),new q(3391569614,3928383900),new q(3515267271,566280711),new q(3940187606,3454069534),new q(4118630271,4000239992),new q(116418474,1914138554),new q(174292421,2731055270),new q(289380356,3203993006),new q(460393269, +320620315),new q(685471733,587496836),new q(852142971,1086792851),new q(1017036298,365543100),new q(1126000580,2618297676),new q(1288033470,3409855158),new q(1501505948,4234509866),new q(1607167915,987167468),new q(1816402316,1246189591)],s="SHA-384"===d?[new q(3418070365,3238371032),new q(1654270250,914150663),new q(2438529370,812702999),new q(355462360,4144912697),new q(1731405415,4290775857),new q(41048885895,1750603025),new q(3675008525,1694076839),new q(1203062813,3204075428)]:[new q(1779033703, +4089235720),new q(3144134277,2227873595),new q(1013904242,4271175723),new q(2773480762,1595750129),new q(1359893119,2917565137),new q(2600822924,725511199),new q(528734635,4215389547),new q(1541459225,327033209)];a[c>>5]|=128<<24-c%32;a[e]=c;sa=a.length;for(Y=0;YL?new q(a[L*ca+Y],a[L*ca+Y+1]):fa(ia(Z[L-2]),Z[L-7],ha(Z[L-15]),Z[L-16]),B=ga(A,ka(h),la(h,k,j),na[L],Z[L]),C=O(ja(c),ma(c,e,f)),A=j,j=k,k=h,h=O(g, +B),g=f,f=e,e=c,c=O(B,C);s[0]=O(c,s[0]);s[1]=O(e,s[1]);s[2]=O(f,s[2]);s[3]=O(g,s[3]);s[4]=O(h,s[4]);s[5]=O(k,s[5]);s[6]=O(j,s[6]);s[7]=O(A,s[7])}switch(d){case "SHA-224":return[s[0],s[1],s[2],s[3],s[4],s[5],s[6]];case "SHA-256":return s;case "SHA-384":return[s[0].highOrder,s[0].lowOrder,s[1].highOrder,s[1].lowOrder,s[2].highOrder,s[2].lowOrder,s[3].highOrder,s[3].lowOrder,s[4].highOrder,s[4].lowOrder,s[5].highOrder,s[5].lowOrder];case "SHA-512":return[s[0].highOrder,s[0].lowOrder,s[1].highOrder,s[1].lowOrder, +s[2].highOrder,s[2].lowOrder,s[3].highOrder,s[3].lowOrder,s[4].highOrder,s[4].lowOrder,s[5].highOrder,s[5].lowOrder,s[6].highOrder,s[6].lowOrder,s[7].highOrder,s[7].lowOrder];default:return[]}},C=function(b,d){this.strToHash=this.strBinLen=this.sha512=this.sha384=this.sha256=this.sha224=this.sha1=null;if("HEX"===d){if(0!==b.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*b.length;this.strToHash=c(b)}else if("ASCII"===d||"undefined"===typeof d)this.strBinLen=8*b.length,this.strToHash= +a(b);else return"UNKNOWN TEXT INPUT TYPE"};C.prototype={getHash:function(a,b){var c=null,g=this.strToHash.slice();switch(b){case "HEX":c=d;break;case "B64":c=e;break;case "ASCII":c=f;break;default:return"FORMAT NOT RECOGNIZED"}switch(a){case "SHA-1":if(null===this.sha1)this.sha1=A(g,this.strBinLen);return c(this.sha1);case "SHA-224":if(null===this.sha224)this.sha224=B(g,this.strBinLen,a);return c(this.sha224);case "SHA-256":if(null===this.sha256)this.sha256=B(g,this.strBinLen,a);return c(this.sha256); +case "SHA-384":if(null===this.sha384)this.sha384=B(g,this.strBinLen,a);return c(this.sha384);case "SHA-512":if(null===this.sha512)this.sha512=B(g,this.strBinLen,a);return c(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(b,g,h,k){var j,m,l,p,o;m=[];var t=[];switch(k){case "HEX":k=d;break;case "B64":k=e;break;case "ASCII":k=f;break;default:return"FORMAT NOT RECOGNIZED"}switch(h){case "SHA-1":j=64;o=160;break;case "SHA-224":j=64;o=224;break;case "SHA-256":j=64;o=256;break;case "SHA-384":j= +128;o=384;break;case "SHA-512":j=128;o=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===g){if(0!==b.length%2)return"KEY MUST BE IN BYTE INCREMENTS";g=c(b);p=4*b.length}else if("ASCII"===g)g=a(b),p=8*b.length;else return"UNKNOWN KEY INPUT TYPE";b=8*j;l=j/4-1;j

p/8&&(g[l]&=4294967040);for(j=0;j<=l;j+=1)m[j]=g[j]^909522486,t[j]=g[j]^1549556828;"SHA-1"===h?(m=A(m.concat(this.strToHash),b+this.strBinLen),m=A(t.concat(m),b+o)):(m=B(m.concat(this.strToHash), +b+this.strBinLen,h),m=B(t.concat(m),b+o,h));return k(m)}};return C}();function str_sha1(b){return(new jsSHA(b,"ASCII")).getHash("SHA-1","ASCII")}function str_sha224(b){return(new jsSHA(b,"ASCII")).getHash("SHA-224","ASCII")}function str_sha256(b){return(new jsSHA(b,"ASCII")).getHash("SHA-256","ASCII")}function str_sha384(b){return(new jsSHA(b,"ASCII")).getHash("SHA-384","ASCII")}function str_sha512(b){return(new jsSHA(b,"ASCII")).getHash("SHA-512","ASCII")}var RMDsize=160,X=[]; +function ROL(b,a){return new Number(b<>>32-a)}function F(b,a,c){return new Number(b^a^c)}function G(b,a,c){return new Number(b&a|~b&c)}function H(b,a,c){return new Number((b|~a)^c)}function I(b,a,c){return new Number(b&c|a&~c)}function J(b,a,c){return new Number(b^(a|~c))} +function mixOneRound(b,a,c,d,e,f,g,h){switch(h){case 0:b+=F(a,c,d)+f+0;break;case 1:b+=G(a,c,d)+f+1518500249;break;case 2:b+=H(a,c,d)+f+1859775393;break;case 3:b+=I(a,c,d)+f+2400959708;break;case 4:b+=J(a,c,d)+f+2840853838;break;case 5:b+=J(a,c,d)+f+1352829926;break;case 6:b+=I(a,c,d)+f+1548603684;break;case 7:b+=H(a,c,d)+f+1836072691;break;case 8:b+=G(a,c,d)+f+2053994217;break;case 9:b+=F(a,c,d)+f+0;break;default:document.write("Bogus round number")}b=ROL(b,g)+e;c=ROL(c,10);h=[];h[0]=b&4294967295; +h[1]=a&4294967295;h[2]=c&4294967295;h[3]=d&4294967295;h[4]=e&4294967295;h[5]=f;h[6]=g;return h}function MDinit(b){b[0]=1732584193;b[1]=4023233417;b[2]=2562383102;b[3]=271733878;b[4]=3285377520} +var ROLs=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]],indexes=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12, +0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]]; +function compress(b,a){blockA=[];blockB=[];for(var c,d=0;5>d;d++)blockA[d]=new Number(b[d]),blockB[d]=new Number(b[d]);for(var e=0,f=0;5>f;f++)for(d=0;16>d;d++)c=mixOneRound(blockA[(e+0)%5],blockA[(e+1)%5],blockA[(e+2)%5],blockA[(e+3)%5],blockA[(e+4)%5],a[indexes[f][d]],ROLs[f][d],f),blockA[(e+0)%5]=c[0],blockA[(e+1)%5]=c[1],blockA[(e+2)%5]=c[2],blockA[(e+3)%5]=c[3],blockA[(e+4)%5]=c[4],e+=4;e=0;for(f=5;10>f;f++)for(d=0;16>d;d++)c=mixOneRound(blockB[(e+0)%5],blockB[(e+1)%5],blockB[(e+2)%5],blockB[(e+ +3)%5],blockB[(e+4)%5],a[indexes[f][d]],ROLs[f][d],f),blockB[(e+0)%5]=c[0],blockB[(e+1)%5]=c[1],blockB[(e+2)%5]=c[2],blockB[(e+3)%5]=c[3],blockB[(e+4)%5]=c[4],e+=4;blockB[3]+=blockA[2]+b[1];b[1]=b[2]+blockA[3]+blockB[4];b[2]=b[3]+blockA[4]+blockB[0];b[3]=b[4]+blockA[0]+blockB[1];b[4]=b[0]+blockA[1]+blockB[2];b[0]=blockB[3]}function zeroX(b){for(var a=0;16>a;a++)b[a]=0} +function MDfinish(b,a,c,d){var e=Array(16);zeroX(e);for(var f=0,g=0;g<(c&63);g++)e[g>>>2]^=(a.charCodeAt(f++)&255)<<8*(g&3);e[c>>>2&15]^=1<<8*(c&3)+7;55<(c&63)&&(compress(b,e),e=Array(16),zeroX(e));e[14]=c<<3;e[15]=c>>>29|d<<3;compress(b,e)}function BYTES_TO_DWORD(b){var a=(b.charCodeAt(3)&255)<<24,a=a|(b.charCodeAt(2)&255)<<16,a=a|(b.charCodeAt(1)&255)<<8;return a|=b.charCodeAt(0)&255} +function RMD(b){var a=Array(RMDsize/32),c=Array(RMDsize/8),d,e;MDinit(a);d=b.length;var f=Array(16);zeroX(f);var g=0;for(e=d;63h;h++)f[h]=BYTES_TO_DWORD(b.substr(g,4)),g+=4;compress(a,f)}MDfinish(a,b.substr(g),d,0);for(h=0;h>>2]&255,c[h+1]=a[h>>>2]>>>8&255,c[h+2]=a[h>>>2]>>>16&255,c[h+3]=a[h>>>2]>>>24&255;return c}function RMDstring(b){for(var b=RMD(b),a="",c=0;cb&&(b=(b&2147483647)+2147483648);return b};Blowfish.prototype._F=function(b){var a,c,d;d=b&255;b>>>=8;c=b&255;b>>>=8;a=b&255;b=this.sboxes[0][b>>>8&255]+this.sboxes[1][a];b^=this.sboxes[2][c];return b+=this.sboxes[3][d]}; +Blowfish.prototype._encrypt_block=function(b){var a=b[0],c=b[1],d;for(d=0;d>>24-8*a&255,b[a+d]=c[1]>>>24-8*a&255;return b}; +Blowfish.prototype._decrypt_block=function(b){var a=b[0],c=b[1],d;for(d=this.NN+1;1e;++e)d=d<<8|b[c]&255,++c>=b.length&&(c=0);this.parray[a]=this.PARRAY[a]^d}this.sboxes=[];for(a=0;4>a;++a){this.sboxes[a]=[];for(c=0;256>c;++c)this.sboxes[a][c]=this.SBOXES[a][c]}b=[0,0];for(a=0;aa;++a)for(c=0;256>c;c+=2)this._encrypt_block(b),this.sboxes[a][c+0]=b[0],this.sboxes[a][c+1]=b[1]}; +function BFencrypt(b,a){var c=new Blowfish;c.init(util.str2bin(a));return c.encrypt_block(b)}function desede(b,a){var c=a.substring(0,8),d=a.substring(8,16),e=a.substring(16,24);return util.str2bin(des(des_createKeys(e),des(des_createKeys(d),des(des_createKeys(c),util.bin2str(b),!0,0,null,null),!1,0,null,null),!0,0,null,null))} +function des(b,a,c,d,e,f){var g=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],h=[-2146402272,-2147450880, 32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880, 32800,-2147483648,-2146435040,-2146402272,1081344],k=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800, 131592,8,134348808,131584],j=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],l=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688, 1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],o=[536870928,541065216, -16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],s=[2097152, -69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],q=[268439616,4096,262144,268701760,268435456, -268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696],m=0,z,x,v,t,r,N,T,K,P,M,w,B,W=b.length,E=0,C=32==a.length? -3:9;N=3==C?c?[0,32,2]:[30,-2,-2]:c?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2];2==f?b+=" ":1==f?(f=8-W%8,b+=String.fromCharCode(f,f,f,f,f,f,f,f),8==f&&(W+=8)):f||(b+="\x00\x00\x00\x00\x00\x00\x00\x00");tempresult=result="";1==d&&(T=e.charCodeAt(m++)<<24|e.charCodeAt(m++)<<16|e.charCodeAt(m++)<<8|e.charCodeAt(m++),P=e.charCodeAt(m++)<<24|e.charCodeAt(m++)<<16|e.charCodeAt(m++)<<8|e.charCodeAt(m++),m=0);for(;m>>4^r)&252645135;r^=f;t^=f<<4;f=(t>>>16^r)&65535;r^=f;t^=f<<16;f=(r>>>2^t)&858993459;t^=f;r^=f<<2;f=(r>>>8^t)&16711935;t^=f;r^=f<<8;f=(t>>>1^r)&1431655765;r^=f;t^=f<<1;t=t<<1|t>>>31;r=r<<1|r>>>31;for(z=0;z>>4|r<<28)^a[e+1],f=t,t=r,r=f^(g[x>>>24&63]|j[x>>>16&63]|o[x>>>8&63]|q[x&63]|h[v>>>24&63]|k[v>>>16&63]|l[v>>> -8&63]|s[v&63]);f=t;t=r;r=f}t=t>>>1|t<<31;r=r>>>1|r<<31;f=(t>>>1^r)&1431655765;r^=f;t^=f<<1;f=(r>>>8^t)&16711935;t^=f;r^=f<<8;f=(r>>>2^t)&858993459;t^=f;r^=f<<2;f=(t>>>16^r)&65535;r^=f;t^=f<<16;f=(t>>>4^r)&252645135;r^=f;t^=f<<4;1==d&&(c?(T=t,P=r):(t^=K,r^=M));tempresult+=String.fromCharCode(t>>>24,t>>>16&255,t>>>8&255,t&255,r>>>24,r>>>16&255,r>>>8&255,r&255);E+=8;512==E&&(result+=tempresult,tempresult="",E=0)}result+=tempresult;return result=result.replace(/\0*$/g,"")} -function des_createKeys(a){pc2bytes0=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964];pc2bytes1=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697];pc2bytes2=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272];pc2bytes3=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952, +16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],r=[2097152, +69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],p=[268439616,4096,262144,268701760,268435456, +268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696],m=0,y,x,v,u,t,E,Q,D,M,K,w,z,T=a.length,A=0,B=32==b.length? +3:9;E=3==B?c?[0,32,2]:[30,-2,-2]:c?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2];2==f?a+=" ":1==f?(f=8-T%8,a+=String.fromCharCode(f,f,f,f,f,f,f,f),8==f&&(T+=8)):f||(a+="\x00\x00\x00\x00\x00\x00\x00\x00");tempresult=result="";1==d&&(Q=e.charCodeAt(m++)<<24|e.charCodeAt(m++)<<16|e.charCodeAt(m++)<<8|e.charCodeAt(m++),M=e.charCodeAt(m++)<<24|e.charCodeAt(m++)<<16|e.charCodeAt(m++)<<8|e.charCodeAt(m++),m=0);for(;m>>4^t)&252645135;t^=f;u^=f<<4;f=(u>>>16^t)&65535;t^=f;u^=f<<16;f=(t>>>2^u)&858993459;u^=f;t^=f<<2;f=(t>>>8^u)&16711935;u^=f;t^=f<<8;f=(u>>>1^t)&1431655765;t^=f;u^=f<<1;u=u<<1|u>>>31;t=t<<1|t>>>31;for(y=0;y>>4|t<<28)^b[e+1],f=u,u=t,t=f^(h[x>>>24&63]|j[x>>>16&63]|o[x>>>8&63]|p[x&63]|g[v>>>24&63]|k[v>>>16&63]|l[v>>> +8&63]|r[v&63]);f=u;u=t;t=f}u=u>>>1|u<<31;t=t>>>1|t<<31;f=(u>>>1^t)&1431655765;t^=f;u^=f<<1;f=(t>>>8^u)&16711935;u^=f;t^=f<<8;f=(t>>>2^u)&858993459;u^=f;t^=f<<2;f=(u>>>16^t)&65535;t^=f;u^=f<<16;f=(u>>>4^t)&252645135;t^=f;u^=f<<4;1==d&&(c?(Q=u,M=t):(u^=D,t^=K));tempresult+=String.fromCharCode(u>>>24,u>>>16&255,u>>>8&255,u&255,t>>>24,t>>>16&255,t>>>8&255,t&255);A+=8;512==A&&(result+=tempresult,tempresult="",A=0)}result+=tempresult;return result=result.replace(/\0*$/g,"")} +function des_createKeys(b){pc2bytes0=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964];pc2bytes1=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697];pc2bytes2=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272];pc2bytes3=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952, 139264,2236416,134356992,136454144];pc2bytes4=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256];pc2bytes5=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488];pc2bytes6=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746];pc2bytes7=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032, 537069568];pc2bytes8=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578];pc2bytes9=[0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488];pc2bytes10=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800];pc2bytes11=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744]; -pc2bytes12=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128];pc2bytes13=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261];for(var b=8>>4^right)&252645135; +pc2bytes12=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128];pc2bytes13=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261];for(var a=8>>4^right)&252645135; right^=k;left^=k<<4;k=(right>>>-16^left)&65535;left^=k;right^=k<<-16;k=(left>>>2^right)&858993459;right^=k;left^=k<<2;k=(right>>>-16^left)&65535;left^=k;right^=k<<-16;k=(left>>>1^right)&1431655765;right^=k;left^=k<<1;k=(right>>>8^left)&16711935;left^=k;right^=k<<8;k=(left>>>1^right)&1431655765;right^=k;left^=k<<1;k=left<<8|right>>>20&240;left=right<<24|right<<8&16711680|right>>>8&65280|right>>>24&240;right=k;for(i=0;i>>26,right=right<<2|right>>>26):(left=left<< -1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,e=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],f=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],k=(f>>>16^e)&65535,c[g++]=e^k,c[g++]=f^k<<16}return c} -function cast5_encrypt(a,b){var c=new openpgp_symenc_cast5;c.setKey(util.str2bin(b));return c.encrypt(a)} -function openpgp_symenc_cast5(){function a(a,b,c){a=b+a;c=a<>>32-c;return(f[0][c>>>24]^f[1][c>>>16&255])-f[2][c>>>8&255]+f[3][c&255]}function b(a,b,c){a^=b;c=a<>>32-c;return f[0][c>>>24]-f[1][c>>>16&255]+f[2][c>>>8&255]^f[3][c&255]}function c(a,b,c){a=b-a;c=a<>>32-c;return(f[0][c>>>24]+f[1][c>>>16&255]^f[2][c>>>8&255])-f[3][c&255]}this.BlockSize=8;this.KeySize=16;this.setKey=function(a){this.masking=Array(16);this.rotate=Array(16);this.reset();if(a.length==this.KeySize)this.keySchedule(a); -else return util.print_error("cast5.js: CAST-128: keys must be 16 bytes"),!1;return!0};this.reset=function(){for(var a=0;16>a;a++)this.masking[a]=0,this.rotate[a]=0};this.getBlockSize=function(){return BlockSize};this.encrypt=function(d){var e=Array(d.length);for(i=0;i>>24&255;e[i+1]=j>>>16&255;e[i+2]=j>>>8&255;e[i+3]=j&255;e[i+4]=f>>>24&255;e[i+5]=f>>>16&255;e[i+6]=f>>>8&255;e[i+7]=f&255}return e};this.decrypt=function(d){var e=Array(d.length);for(i=0;i>>24&255;e[i+1]=j>>>16&255;e[i+2]=j>>>8&255;e[i+3]=j&255;e[i+4]=f>>>24&255;e[i+5]=f>>16&255;e[i+6]=f>>8&255;e[i+7]=f&255}return e};var d=Array(4);d[0]=Array(4);d[0][0]=[4,0,13,15,12,14,8];d[0][1]=[5,2,16,18,17,19,10];d[0][2]=[6,3,23,22,21,20,9];d[0][3]=[7,1,26,25,27,24,11];d[1]=Array(4);d[1][0]=[0, +1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,e=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],f=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],k=(f>>>16^e)&65535,c[h++]=e^k,c[h++]=f^k<<16}return c} +function cast5_encrypt(b,a){var c=new openpgp_symenc_cast5;c.setKey(util.str2bin(a));return c.encrypt(b)} +function openpgp_symenc_cast5(){function b(a,b,c){a=b+a;c=a<>>32-c;return(f[0][c>>>24]^f[1][c>>>16&255])-f[2][c>>>8&255]+f[3][c&255]}function a(a,b,c){a^=b;c=a<>>32-c;return f[0][c>>>24]-f[1][c>>>16&255]+f[2][c>>>8&255]^f[3][c&255]}function c(a,b,c){a=b-a;c=a<>>32-c;return(f[0][c>>>24]+f[1][c>>>16&255]^f[2][c>>>8&255])-f[3][c&255]}this.BlockSize=8;this.KeySize=16;this.setKey=function(a){this.masking=Array(16);this.rotate=Array(16);this.reset();if(a.length==this.KeySize)this.keySchedule(a); +else return util.print_error("cast5.js: CAST-128: keys must be 16 bytes"),!1;return!0};this.reset=function(){for(var a=0;16>a;a++)this.masking[a]=0,this.rotate[a]=0};this.getBlockSize=function(){return BlockSize};this.encrypt=function(d){var e=Array(d.length);for(i=0;i>>24&255;e[i+1]=j>>>16&255;e[i+2]=j>>>8&255;e[i+3]=j&255;e[i+4]=f>>>24&255;e[i+5]=f>>>16&255;e[i+6]=f>>>8&255;e[i+7]=f&255}return e};this.decrypt=function(d){var e=Array(d.length);for(i=0;i>>24&255;e[i+1]=j>>>16&255;e[i+2]=j>>>8&255;e[i+3]=j&255;e[i+4]=f>>>24&255;e[i+5]=f>>16&255;e[i+6]=f>>8&255;e[i+7]=f&255}return e};var d=Array(4);d[0]=Array(4);d[0][0]=[4,0,13,15,12,14,8];d[0][1]=[5,2,16,18,17,19,10];d[0][2]=[6,3,23,22,21,20,9];d[0][3]=[7,1,26,25,27,24,11];d[1]=Array(4);d[1][0]=[0, 6,21,23,20,22,16];d[1][1]=[1,4,0,2,1,3,18];d[1][2]=[2,5,7,6,5,4,17];d[1][3]=[3,7,10,9,11,8,19];d[2]=Array(4);d[2][0]=[4,0,13,15,12,14,8];d[2][1]=[5,2,16,18,17,19,10];d[2][2]=[6,3,23,22,21,20,9];d[2][3]=[7,1,26,25,27,24,11];d[3]=Array(4);d[3][0]=[0,6,21,23,20,22,16];d[3][1]=[1,4,0,2,1,3,18];d[3][2]=[2,5,7,6,5,4,17];d[3][3]=[3,7,10,9,11,8,19];var e=Array(4);e[0]=Array(4);e[0][0]=[24,25,23,22,18];e[0][1]=[26,27,21,20,22];e[0][2]=[28,29,19,18,25];e[0][3]=[30,31,17,16,28];e[1]=Array(4);e[1][0]=[3,2,12, -13,8];e[1][1]=[1,0,14,15,13];e[1][2]=[7,6,8,9,3];e[1][3]=[5,4,10,11,7];e[2]=Array(4);e[2][0]=[19,18,28,29,25];e[2][1]=[17,16,30,31,28];e[2][2]=[23,22,24,25,18];e[2][3]=[21,20,26,27,22];e[3]=Array(4);e[3][0]=[8,9,7,6,3];e[3][1]=[10,11,5,4,7];e[3][2]=[12,13,3,2,8];e[3][3]=[14,15,1,0,13];this.keySchedule=function(a){for(var b=Array(8),c=Array(32),j=0;4>j;j++){var l=4*j;b[j]=a[l]<<24|a[l+1]<<16|a[l+2]<<8|a[l+3]}for(var a=[6,7,4,5],o=j=0;2>o;o++)for(var s=0;4>s;s++){for(l=0;4>l;l++){var q=d[s][l],m=b[q[1]], -m=m^f[4][b[q[2]>>>2]>>>24-8*(q[2]&3)&255],m=m^f[5][b[q[3]>>>2]>>>24-8*(q[3]&3)&255],m=m^f[6][b[q[4]>>>2]>>>24-8*(q[4]&3)&255],m=m^f[7][b[q[5]>>>2]>>>24-8*(q[5]&3)&255],m=m^f[a[l]][b[q[6]>>>2]>>>24-8*(q[6]&3)&255];b[q[0]]=m}for(l=0;4>l;l++)q=e[s][l],m=f[4][b[q[0]>>>2]>>>24-8*(q[0]&3)&255],m^=f[5][b[q[1]>>>2]>>>24-8*(q[1]&3)&255],m^=f[6][b[q[2]>>>2]>>>24-8*(q[2]&3)&255],m^=f[7][b[q[3]>>>2]>>>24-8*(q[3]&3)&255],m^=f[4+l][b[q[4]>>>2]>>>24-8*(q[4]&3)&255],c[j]=m,j++}for(j=0;16>j;j++)this.masking[j]=c[j], +13,8];e[1][1]=[1,0,14,15,13];e[1][2]=[7,6,8,9,3];e[1][3]=[5,4,10,11,7];e[2]=Array(4);e[2][0]=[19,18,28,29,25];e[2][1]=[17,16,30,31,28];e[2][2]=[23,22,24,25,18];e[2][3]=[21,20,26,27,22];e[3]=Array(4);e[3][0]=[8,9,7,6,3];e[3][1]=[10,11,5,4,7];e[3][2]=[12,13,3,2,8];e[3][3]=[14,15,1,0,13];this.keySchedule=function(a){for(var b=Array(8),c=Array(32),j=0;4>j;j++){var l=4*j;b[j]=a[l]<<24|a[l+1]<<16|a[l+2]<<8|a[l+3]}for(var a=[6,7,4,5],o=j=0;2>o;o++)for(var r=0;4>r;r++){for(l=0;4>l;l++){var p=d[r][l],m=b[p[1]], +m=m^f[4][b[p[2]>>>2]>>>24-8*(p[2]&3)&255],m=m^f[5][b[p[3]>>>2]>>>24-8*(p[3]&3)&255],m=m^f[6][b[p[4]>>>2]>>>24-8*(p[4]&3)&255],m=m^f[7][b[p[5]>>>2]>>>24-8*(p[5]&3)&255],m=m^f[a[l]][b[p[6]>>>2]>>>24-8*(p[6]&3)&255];b[p[0]]=m}for(l=0;4>l;l++)p=e[r][l],m=f[4][b[p[0]>>>2]>>>24-8*(p[0]&3)&255],m^=f[5][b[p[1]>>>2]>>>24-8*(p[1]&3)&255],m^=f[6][b[p[2]>>>2]>>>24-8*(p[2]&3)&255],m^=f[7][b[p[3]>>>2]>>>24-8*(p[3]&3)&255],m^=f[4+l][b[p[4]>>>2]>>>24-8*(p[4]&3)&255],c[j]=m,j++}for(j=0;16>j;j++)this.masking[j]=c[j], this.rotate[j]=c[16+j]&31};var f=Array(8);f[0]=[821772500,2678128395,1810681135,1059425402,505495343,2617265619,1610868032,3483355465,3218386727,2294005173,3791863952,2563806837,1852023008,365126098,3269944861,584384398,677919599,3229601881,4280515016,2002735330,1136869587,3744433750,2289869850,2731719981,2714362070,879511577,1639411079,575934255,717107937,2857637483,576097850,2731753936,1725645E3,2810460463,5111599,767152862,2543075244,1251459544,1383482551,3052681127,3089939183,3612463449,1878520045, 1510570527,2189125840,2431448366,582008916,3163445557,1265446783,1354458274,3529918736,3202711853,3073581712,3912963487,3029263377,1275016285,4249207360,2905708351,3304509486,1442611557,3585198765,2712415662,2731849581,3248163920,2283946226,208555832,2766454743,1331405426,1447828783,3315356441,3108627284,2957404670,2981538698,3339933917,1669711173,286233437,1465092821,1782121619,3862771680,710211251,980974943,1651941557,430374111,2051154026,704238805,4128970897,3144820574,2857402727,948965521,3333752299, 2227686284,718756367,2269778983,2731643755,718440111,2857816721,3616097120,1113355533,2478022182,410092745,1811985197,1944238868,2696854588,1415722873,1682284203,1060277122,1998114690,1503841958,82706478,2315155686,1068173648,845149890,2167947013,1768146376,1993038550,3566826697,3390574031,940016341,3355073782,2328040721,904371731,1205506512,4094660742,2816623006,825647681,85914773,2857843460,1249926541,1417871568,3287612,3211054559,3126306446,1975924523,1353700161,2814456437,2438597621,1800716203, @@ -311,43 +244,7 @@ f[2]=[2381300288,637164959,3952098751,3893414151,1197506559,916448331,2350892612 163866573,3246985393,3776823163,114105080,1903216136,761148244,3571337562,1690750982,3166750252,1037045171,1888456500,2010454850,642736655,616092351,365016990,1185228132,4174898510,1043824992,2023083429,2241598885,3863320456,3279669087,3674716684,108438443,2132974366,830746235,606445527,4173263986,2204105912,1844756978,2532684181,4245352700,2969441100,3796921661,1335562986,4061524517,2720232303,2679424040,634407289,885462008,3294724487,3933892248,2094100220,339117932,4048830727,3202280980,1458155303, 2689246273,1022871705,2464987878,3714515309,353796843,2822958815,4256850100,4052777845,551748367,618185374,3778635579,4020649912,1904685140,3069366075,2670879810,3407193292,2954511620,4058283405,2219449317,3135758300,1120655984,3447565834,1474845562,3577699062,550456716,3466908712,2043752612,881257467,869518812,2005220179,938474677,3305539448,3850417126,1315485940,3318264702,226533026,965733244,321539988,1136104718,804158748,573969341,3708209826,937399083,3290727049,2901666755,1461057207,4013193437, 4066861423,3242773476,2421326174,1581322155,3028952165,786071460,3900391652,3918438532,1485433313,4023619836,3708277595,3678951060,953673138,1467089153,1930354364,1533292819,2492563023,1346121658,1685000834,1965281866,3765933717,4190206607,2052792609,3515332758,690371149,3125873887,2180283551,2903598061,3933952357,436236910,289419410,14314871,1242357089,2904507907,1616633776,2666382180,585885352,3471299210,2699507360,1432659641,277164553,3354103607,770115018,2303809295,3741942315,3177781868,2853364978, -2269453327,3774259834,987383833,1290892879,225909803,1741533526,890078084,1496906255,1111072499,916028167,243534141,1252605537,2204162171,531204876,290011180,3916834213,102027703,237315147,209093447,1486785922,220223953,2758195998,4175039106,82940208,3127791296,2569425252,518464269,1353887104,3941492737,2377294467,3935040926]}function TFencrypt(a,b){var c=[].concat(a),d=createTwofish();d.open(util.str2bin(b),0);c=d.encrypt(c,0);d.close();return c}var MAXINT=4294967295; -function rotb(a,b){return(a<>>8-b)&255}function rotw(a,b){return(a<>>32-b)&MAXINT}function getW(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16|a[b+3]<<24}function setW(a,b,c){a.splice(b,4,c&255,c>>>8&255,c>>>16&255,c>>>24&255)}function setWInv(a,b,c){a.splice(b,4,c>>>24&255,c>>>16&255,c>>>8&255,c&255)}function getB(a,b){return a>>>8*b&255}function getNrBits(a){for(var b=0;0>>=1;return b}function getMask(a){return(1<d;d++)e=c>>>24,c=c<<8&MAXINT|a>>>24,a=a<<8&MAXINT,f=e<<1,e&128&&(f^=333),c^=e^f<<16,f^=e>>>1,e&1&&(f^=166),c^=f<<24|f<<8;return c}function d(a,b){var c,e,f;c=b>>4;e=b&15;f=r[a][c^ -e];c=N[a][P[e]^M[c]];return K[a][P[c]^M[f]]<<4|T[a][f^c]}function e(a,b){var c=getB(a,0),d=getB(a,1),f=getB(a,2),g=getB(a,3);switch(x){case 4:c=w[1][c]^getB(b[3],0),d=w[0][d]^getB(b[3],1),f=w[0][f]^getB(b[3],2),g=w[1][g]^getB(b[3],3);case 3:c=w[1][c]^getB(b[2],0),d=w[1][d]^getB(b[2],1),f=w[0][f]^getB(b[2],2),g=w[0][g]^getB(b[2],3);case 2:c=w[0][w[0][c]^getB(b[1],0)]^getB(b[0],0),d=w[0][w[1][d]^getB(b[1],1)]^getB(b[0],1),f=w[1][w[0][f]^getB(b[1],2)]^getB(b[0],2),g=w[1][w[1][g]^getB(b[1],3)]^getB(b[0], -3)}return B[0][c]^B[1][d]^B[2][f]^B[3][g]}c=a;var o,s,q,m;q=[];m=[];var z=[],x,v=[],t,r=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],N=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],T=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],K=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],P=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],M=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14, -7],w=[[],[]],B=[[],[],[],[]];c=c.slice(0,32);for(a=c.length;16!=a&&24!=a&&32!=a;)c[a++]=0;for(a=0;a>2]=getW(c,a);for(a=0;256>a;a++)w[0][a]=d(0,a),w[1][a]=d(1,a);for(a=0;256>a;a++)o=w[1][a],s=o^o>>2^[0,90,180,238][o&3],t=o^o>>1^o>>2^[0,238,180,90][o&3],B[0][a]=o+(s<<8)+(t<<16)+(t<<24),B[2][a]=s+(t<<8)+(o<<16)+(t<<24),o=w[0][a],s=o^o>>2^[0,90,180,238][o&3],t=o^o>>1^o>>2^[0,238,180,90][o&3],B[1][a]=t+(t<<8)+(s<<16)+(o<<24),B[3][a]=s+(o<<8)+(t<<16)+(s<<24);x=z.length/2;for(a=0;aa;a+=2)o=16843009*a,s=o+16843009,o=e(o,q),s=rotw(e(s,m),8),f[a]=o+s&MAXINT,f[a+1]=rotw(o+2*s,9);for(a=0;256>a;a++)switch(o=s=q=m=a,x){case 4:o=w[1][o]^getB(v[3],0),s=w[0][s]^getB(v[3],1),q=w[0][q]^getB(v[3],2),m=w[1][m]^getB(v[3],3);case 3:o=w[1][o]^getB(v[2],0),s=w[1][s]^getB(v[2],1),q=w[0][q]^getB(v[2],2),m=w[0][m]^getB(v[2],3);case 2:h[0][a]=B[0][w[0][w[0][o]^getB(v[1],0)]^getB(v[0],0)],h[1][a]=B[1][w[0][w[1][s]^getB(v[1],1)]^getB(v[0], -1)],h[2][a]=B[2][w[1][w[0][q]^getB(v[1],2)]^getB(v[0],2)],h[3][a]=B[3][w[1][w[1][m]^getB(v[1],3)]^getB(v[0],3)]}},close:function(){f=[];h=[[],[],[],[]]},encrypt:function(c,h){d=c;e=h;for(var j=[getW(d,e)^f[0],getW(d,e+4)^f[1],getW(d,e+8)^f[2],getW(d,e+12)^f[3]],l=0;8>l;l++){var o=l,s=j,q=a(s[0]),m=b(s[1]);s[2]=rotw(s[2]^q+m+f[4*o+8]&MAXINT,31);s[3]=rotw(s[3],1)^q+2*m+f[4*o+9]&MAXINT;q=a(s[2]);m=b(s[3]);s[0]=rotw(s[0]^q+m+f[4*o+10]&MAXINT,31);s[1]=rotw(s[1],1)^q+2*m+f[4*o+11]&MAXINT}setW(d,e,j[2]^ -f[4]);setW(d,e+4,j[3]^f[5]);setW(d,e+8,j[0]^f[6]);setW(d,e+12,j[1]^f[7]);e+=16;return d},decrypt:function(c,h){d=c;e=h;for(var j=[getW(d,e)^f[4],getW(d,e+4)^f[5],getW(d,e+8)^f[6],getW(d,e+12)^f[7]],l=7;0<=l;l--){var o=l,s=j,q=a(s[0]),m=b(s[1]);s[2]=rotw(s[2],1)^q+m+f[4*o+10]&MAXINT;s[3]=rotw(s[3]^q+2*m+f[4*o+11]&MAXINT,31);q=a(s[2]);m=b(s[3]);s[0]=rotw(s[0],1)^q+m+f[4*o+8]&MAXINT;s[1]=rotw(s[1]^q+2*m+f[4*o+9]&MAXINT,31)}setW(d,e,j[2]^f[0]);setW(d,e+4,j[3]^f[1]);setW(d,e+8,j[0]^f[2]);setW(d,e+12,j[1]^ -f[3]);e+=16},finalize:function(){return d}}}function Blowfish(){}Blowfish.prototype.BLOCKSIZE=8; -Blowfish.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110, -2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150, -2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882, -3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752, -2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733, -2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971E4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318, -4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577, -1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166, -1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008, -1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024, -3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743, -4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247, -1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701, -1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260, -2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006, -548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820, -2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200, -2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241, -3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891, -3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409E3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588, -3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493, -1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]]; -Blowfish.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731];Blowfish.prototype.NN=16;Blowfish.prototype._clean=function(a){0>a&&(a=(a&2147483647)+2147483648);return a};Blowfish.prototype._F=function(a){var b,c,d;d=a&255;a>>>=8;c=a&255;a>>>=8;b=a&255;a=this.sboxes[0][a>>>8&255]+this.sboxes[1][b];a^=this.sboxes[2][c];return a+=this.sboxes[3][d]}; -Blowfish.prototype._encrypt_block=function(a){var b=a[0],c=a[1],d;for(d=0;d>>24-8*b&255,a[b+d]=c[1]>>>24-8*b&255;return a}; -Blowfish.prototype._decrypt_block=function(a){var b=a[0],c=a[1],d;for(d=this.NN+1;1e;++e)d=d<<8|a[c]&255,++c>=a.length&&(c=0);this.parray[b]=this.PARRAY[b]^d}this.sboxes=[];for(b=0;4>b;++b){this.sboxes[b]=[];for(c=0;256>c;++c)this.sboxes[b][c]=this.SBOXES[b][c]}a=[0,0];for(b=0;bb;++b)for(c=0;256>c;c+=2)this._encrypt_block(a),this.sboxes[b][c+0]=a[0],this.sboxes[b][c+1]=a[1]}; -function BFencrypt(a,b){var c=new Blowfish;c.init(util.str2bin(b));return c.encrypt_block(a)} +2269453327,3774259834,987383833,1290892879,225909803,1741533526,890078084,1496906255,1111072499,916028167,243534141,1252605537,2204162171,531204876,290011180,3916834213,102027703,237315147,209093447,1486785922,220223953,2758195998,4175039106,82940208,3127791296,2569425252,518464269,1353887104,3941492737,2377294467,3935040926]} var Rcon=[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145],S=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80, 60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65, 153,45,15,176,84,187,22],T1=[2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849, @@ -371,104 +268,206 @@ var Rcon=[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53, 3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752, 3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498, 967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407, -1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246];function B0(a){return a&255}function B1(a){return a>>8&255}function B2(a){return a>>16&255} -function B3(a){return a>>24&255}function F1(a,b,c,d){return B1(T1[a&255])|B1(T1[b>>8&255])<<8|B1(T1[c>>16&255])<<16|B1(T1[d>>>24])<<24}function packBytes(a){var b,c,d=a.length,e=Array(d/4);if(a&&!(d%4)){for(b=0,c=0;cc;d++,c++)f[a][c]=k[d];4==c&&(a++,c=0)}for(;ac;d++,c++)f[a][c]=k[d];4==c&&(a++,c=0)}}this.rounds=e;this.rk=f;return this} -function AESencrypt(a,b){var c,d,e,f,h,g=packBytes(a),k=b.rounds,j=g[0],l=g[1],o=g[2];h=g[3];for(c=0;c>8&255]^T3[f>>16&255]^T4[h>>>24],l=T1[e&255]^T2[f>>8&255]^T3[h>>16&255]^T4[d>>>24],o=T1[f&255]^T2[h>>8&255]^T3[d>>16&255]^T4[e>>>24],h=T1[h&255]^T2[d>>8&255]^T3[e>>16&255]^T4[f>>>24];c=k-1;d=j^b.rk[c][0];e=l^b.rk[c][1];f=o^b.rk[c][2];h^=b.rk[c][3];g[0]=F1(d,e,f,h)^b.rk[k][0];g[1]=F1(e,f,h,d)^b.rk[k][1];g[2]=F1(f, -h,d,e)^b.rk[k][2];g[3]=F1(h,d,e,f)^b.rk[k][3];return unpackBytes(g)} -function openpgp_cfb_encrypt(a,b,c,d,e,f){var h=Array(d),g=Array(d),a=a+a.charAt(d-2)+a.charAt(d-1);util.print_debug("prefixrandom:"+util.hexstrdump(a));for(var k="",j=0;jb*h;){for(var e=a(f,c),f=d.substring(h*b,h*b+b),j=0;jb*h;){for(var k=a(f,c),f=d.substring(h*b+0,h*b+b+0),e=0;e>5]|=(a.charCodeAt(d/8)&255)<<24-d%32;return b},c=function(a){var b=[],c=a.length,d,e;for(d=0;d>3]|=e<<24-4*(d%8)}return b},d=function(a){var b="",c=4*a.length,d,e;for(d=0;d>2]>>8*(3-d%4),b+="0123456789abcdef".charAt(e>>4&15)+"0123456789abcdef".charAt(e&15);return b},e=function(a){var b= -"",c=4*a.length,d,e,f;for(d=0;d>2]>>8*(3-d%4)&255)<<16|(a[d+1>>2]>>8*(3-(d+1)%4)&255)<<8|a[d+2>>2]>>8*(3-(d+2)%4)&255;for(e=0;4>e;e+=1)b=8*d+6*e<=32*a.length?b+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>6*(3-e)&63):b+""}return b},f=function(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b},h=function(a,b){return a<>>32-b},g=function(a,b){return a>>>b|a<<32-b},k=function(b,c){return 32>=c?new a(b.highOrder>>> -c|b.lowOrder<<32-c,b.lowOrder>>>c|b.highOrder<<32-c):new a(b.lowOrder>>>c|b.highOrder<<32-c,b.highOrder>>>c|b.lowOrder<<32-c)},j=function(b,c){return 32>=c?new a(b.highOrder>>>c,b.lowOrder>>>c|b.highOrder<<32-c):new a(0,b.highOrder<<32-c)},l=function(a,b,c){return a&b^~a&c},o=function(b,c,d){return new a(b.highOrder&c.highOrder^~b.highOrder&d.highOrder,b.lowOrder&c.lowOrder^~b.lowOrder&d.lowOrder)},s=function(a,b,c){return a&b^a&c^b&c},q=function(b,c,d){return new a(b.highOrder&c.highOrder^b.highOrder& -d.highOrder^c.highOrder&d.highOrder,b.lowOrder&c.lowOrder^b.lowOrder&d.lowOrder^c.lowOrder&d.lowOrder)},m=function(a){return g(a,2)^g(a,13)^g(a,22)},z=function(b){var c=k(b,28),d=k(b,34),b=k(b,39);return new a(c.highOrder^d.highOrder^b.highOrder,c.lowOrder^d.lowOrder^b.lowOrder)},x=function(a){return g(a,6)^g(a,11)^g(a,25)},v=function(b){var c=k(b,14),d=k(b,18),b=k(b,41);return new a(c.highOrder^d.highOrder^b.highOrder,c.lowOrder^d.lowOrder^b.lowOrder)},t=function(a){return g(a,7)^g(a,18)^a>>>3}, -r=function(b){var c=k(b,1),d=k(b,8),b=j(b,7);return new a(c.highOrder^d.highOrder^b.highOrder,c.lowOrder^d.lowOrder^b.lowOrder)},N=function(a){return g(a,17)^g(a,19)^a>>>10},T=function(b){var c=k(b,19),d=k(b,61),b=j(b,6);return new a(c.highOrder^d.highOrder^b.highOrder,c.lowOrder^d.lowOrder^b.lowOrder)},K=function(a,b){var c=(a&65535)+(b&65535);return((a>>>16)+(b>>>16)+(c>>>16)&65535)<<16|c&65535},P=function(a,b,c,d){var e=(a&65535)+(b&65535)+(c&65535)+(d&65535);return((a>>>16)+(b>>>16)+(c>>>16)+ -(d>>>16)+(e>>>16)&65535)<<16|e&65535},M=function(a,b,c,d,e){var f=(a&65535)+(b&65535)+(c&65535)+(d&65535)+(e&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16)&65535)<<16|f&65535},w=function(b,c){var d,e,f;d=(b.lowOrder&65535)+(c.lowOrder&65535);e=(b.lowOrder>>>16)+(c.lowOrder>>>16)+(d>>>16);f=(e&65535)<<16|d&65535;d=(b.highOrder&65535)+(c.highOrder&65535)+(e>>>16);e=(b.highOrder>>>16)+(c.highOrder>>>16)+(d>>>16);return new a((e&65535)<<16|d&65535,f)},B=function(b,c,d,e){var f,g, -h;f=(b.lowOrder&65535)+(c.lowOrder&65535)+(d.lowOrder&65535)+(e.lowOrder&65535);g=(b.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16);h=(g&65535)<<16|f&65535;f=(b.highOrder&65535)+(c.highOrder&65535)+(d.highOrder&65535)+(e.highOrder&65535)+(g>>>16);g=(b.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16);return new a((g&65535)<<16|f&65535,h)},W=function(b,c,d,e,f){var g,h,j;g=(b.lowOrder&65535)+(c.lowOrder&65535)+(d.lowOrder&65535)+(e.lowOrder& -65535)+(f.lowOrder&65535);h=(b.lowOrder>>>16)+(c.lowOrder>>>16)+(d.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16);j=(h&65535)<<16|g&65535;g=(b.highOrder&65535)+(c.highOrder&65535)+(d.highOrder&65535)+(e.highOrder&65535)+(f.highOrder&65535)+(h>>>16);h=(b.highOrder>>>16)+(c.highOrder>>>16)+(d.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16);return new a((h&65535)<<16|g&65535,j)},E=function(a,b){var c=[],d,e,f,g,j,k,l,m,q,o=[1732584193,4023233417,2562383102,271733878,3285377520], -r=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708, -2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];a[b>>5]|=128<<24-b%32;a[(b+65>>9<<4)+15]=b;q=a.length;for(l=0;lm;m+=1)c[m]= -16>m?a[m+l]:h(c[m-3]^c[m-8]^c[m-14]^c[m-16],1),k=20>m?M(h(d,5),e&f^~e&g,j,r[m],c[m]):40>m?M(h(d,5),e^f^g,j,r[m],c[m]):60>m?M(h(d,5),s(e,f,g),j,r[m],c[m]):M(h(d,5),e^f^g,j,r[m],c[m]),j=g,g=f,f=h(e,30),e=d,d=k;o[0]=K(d,o[0]);o[1]=K(e,o[1]);o[2]=K(f,o[2]);o[3]=K(g,o[3]);o[4]=K(j,o[4])}return o},C=function(b,c,d){var e,f,g,h,j,k,V,C,E,u,D,Y,L,fa,ea,Q,ga,ha,ia,ja,ka,la,ma,na,p,oa,ba=[],ra;if("SHA-224"===d||"SHA-256"===d)D=64,e=(c+65>>9<<4)+15,fa=16,ea=1,p=Number,Q=K,ga=P,ha=M,ia=t,ja=N,ka=m,la=x,na=s, -ma=l,oa=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804, -4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],u="SHA-224"===d?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];else if("SHA-384"===d||"SHA-512"===d)D=80,e=(c+128>>10<<5)+31,fa=32,ea=2,p=a,Q=w,ga=B,ha=W,ia=r,ja=T,ka=z,la=v,na=q, -ma=o,oa=[new p(1116352408,3609767458),new p(1899447441,602891725),new p(3049323471,3964484399),new p(3921009573,2173295548),new p(961987163,4081628472),new p(1508970993,3053834265),new p(2453635748,2937671579),new p(2870763221,3664609560),new p(3624381080,2734883394),new p(310598401,1164996542),new p(607225278,1323610764),new p(1426881987,3590304994),new p(1925078388,4068182383),new p(2162078206,991336113),new p(2614888103,633803317),new p(3248222580,3479774868),new p(3835390401,2666613458),new p(4022224774, -944711139),new p(264347078,2341262773),new p(604807628,2007800933),new p(770255983,1495990901),new p(1249150122,1856431235),new p(1555081692,3175218132),new p(1996064986,2198950837),new p(2554220882,3999719339),new p(2821834349,766784016),new p(2952996808,2566594879),new p(3210313671,3203337956),new p(3336571891,1034457026),new p(3584528711,2466948901),new p(113926993,3758326383),new p(338241895,168717936),new p(666307205,1188179964),new p(773529912,1546045734),new p(1294757372,1522805485),new p(1396182291, -2643833823),new p(1695183700,2343527390),new p(1986661051,1014477480),new p(2177026350,1206759142),new p(2456956037,344077627),new p(2730485921,1290863460),new p(2820302411,3158454273),new p(3259730800,3505952657),new p(3345764771,106217008),new p(3516065817,3606008344),new p(3600352804,1432725776),new p(4094571909,1467031594),new p(275423344,851169720),new p(430227734,3100823752),new p(506948616,1363258195),new p(659060556,3750685593),new p(883997877,3785050280),new p(958139571,3318307427),new p(1322822218, -3812723403),new p(1537002063,2003034995),new p(1747873779,3602036899),new p(1955562222,1575990012),new p(2024104815,1125592928),new p(2227730452,2716904306),new p(2361852424,442776044),new p(2428436474,593698344),new p(2756734187,3733110249),new p(3204031479,2999351573),new p(3329325298,3815920427),new p(3391569614,3928383900),new p(3515267271,566280711),new p(3940187606,3454069534),new p(4118630271,4000239992),new p(116418474,1914138554),new p(174292421,2731055270),new p(289380356,3203993006),new p(460393269, -320620315),new p(685471733,587496836),new p(852142971,1086792851),new p(1017036298,365543100),new p(1126000580,2618297676),new p(1288033470,3409855158),new p(1501505948,4234509866),new p(1607167915,987167468),new p(1816402316,1246189591)],u="SHA-384"===d?[new p(3418070365,3238371032),new p(1654270250,914150663),new p(2438529370,812702999),new p(355462360,4144912697),new p(1731405415,4290775857),new p(41048885895,1750603025),new p(3675008525,1694076839),new p(1203062813,3204075428)]:[new p(1779033703, -4089235720),new p(3144134277,2227873595),new p(1013904242,4271175723),new p(2773480762,1595750129),new p(1359893119,2917565137),new p(2600822924,725511199),new p(528734635,4215389547),new p(1541459225,327033209)];b[c>>5]|=128<<24-c%32;b[e]=c;ra=b.length;for(Y=0;YL?new p(b[L*ea+Y],b[L*ea+Y+1]):ga(ja(ba[L-2]),ba[L-7],ia(ba[L-15]),ba[L-16]),C=ha(V,la(h),ma(h,j,k),oa[L],ba[L]),E=Q(ka(c),na(c,e,f)),V=k,k=j,j=h, -h=Q(g,C),g=f,f=e,e=c,c=Q(C,E);u[0]=Q(c,u[0]);u[1]=Q(e,u[1]);u[2]=Q(f,u[2]);u[3]=Q(g,u[3]);u[4]=Q(h,u[4]);u[5]=Q(j,u[5]);u[6]=Q(k,u[6]);u[7]=Q(V,u[7])}switch(d){case "SHA-224":return[u[0],u[1],u[2],u[3],u[4],u[5],u[6]];case "SHA-256":return u;case "SHA-384":return[u[0].highOrder,u[0].lowOrder,u[1].highOrder,u[1].lowOrder,u[2].highOrder,u[2].lowOrder,u[3].highOrder,u[3].lowOrder,u[4].highOrder,u[4].lowOrder,u[5].highOrder,u[5].lowOrder];case "SHA-512":return[u[0].highOrder,u[0].lowOrder,u[1].highOrder, -u[1].lowOrder,u[2].highOrder,u[2].lowOrder,u[3].highOrder,u[3].lowOrder,u[4].highOrder,u[4].lowOrder,u[5].highOrder,u[5].lowOrder,u[6].highOrder,u[6].lowOrder,u[7].highOrder,u[7].lowOrder];default:return[]}},D=function(a,d){this.strToHash=this.strBinLen=this.sha512=this.sha384=this.sha256=this.sha224=this.sha1=null;if("HEX"===d){if(0!==a.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*a.length;this.strToHash=c(a)}else if("ASCII"===d||"undefined"===typeof d)this.strBinLen=8*a.length, -this.strToHash=b(a);else return"UNKNOWN TEXT INPUT TYPE"};D.prototype={getHash:function(a,b){var c=null,g=this.strToHash.slice();switch(b){case "HEX":c=d;break;case "B64":c=e;break;case "ASCII":c=f;break;default:return"FORMAT NOT RECOGNIZED"}switch(a){case "SHA-1":if(null===this.sha1)this.sha1=E(g,this.strBinLen);return c(this.sha1);case "SHA-224":if(null===this.sha224)this.sha224=C(g,this.strBinLen,a);return c(this.sha224);case "SHA-256":if(null===this.sha256)this.sha256=C(g,this.strBinLen,a);return c(this.sha256); -case "SHA-384":if(null===this.sha384)this.sha384=C(g,this.strBinLen,a);return c(this.sha384);case "SHA-512":if(null===this.sha512)this.sha512=C(g,this.strBinLen,a);return c(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(a,g,h,j){var k,l,m,o,q;l=[];var r=[];switch(j){case "HEX":j=d;break;case "B64":j=e;break;case "ASCII":j=f;break;default:return"FORMAT NOT RECOGNIZED"}switch(h){case "SHA-1":k=64;q=160;break;case "SHA-224":k=64;q=224;break;case "SHA-256":k=64;q=256;break;case "SHA-384":k= -128;q=384;break;case "SHA-512":k=128;q=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===g){if(0!==a.length%2)return"KEY MUST BE IN BYTE INCREMENTS";g=c(a);o=4*a.length}else if("ASCII"===g)g=b(a),o=8*a.length;else return"UNKNOWN KEY INPUT TYPE";a=8*k;m=k/4-1;ko/8&&(g[m]&=4294967040);for(k=0;k<=m;k+=1)l[k]=g[k]^909522486,r[k]=g[k]^1549556828;"SHA-1"===h?(l=E(l.concat(this.strToHash),a+this.strBinLen),l=E(r.concat(l),a+q)):(l=C(l.concat(this.strToHash), -a+this.strBinLen,h),l=C(r.concat(l),a+q,h));return j(l)}};return D}();function str_sha1(a){return(new jsSHA(a,"ASCII")).getHash("SHA-1","ASCII")}function str_sha224(a){return(new jsSHA(a,"ASCII")).getHash("SHA-224","ASCII")}function str_sha256(a){return(new jsSHA(a,"ASCII")).getHash("SHA-256","ASCII")}function str_sha384(a){return(new jsSHA(a,"ASCII")).getHash("SHA-384","ASCII")}function str_sha512(a){return(new jsSHA(a,"ASCII")).getHash("SHA-512","ASCII")}var RMDsize=160,X=[]; -function ROL(a,b){return new Number(a<>>32-b)}function F(a,b,c){return new Number(a^b^c)}function G(a,b,c){return new Number(a&b|~a&c)}function H(a,b,c){return new Number((a|~b)^c)}function I(a,b,c){return new Number(a&c|b&~c)}function J(a,b,c){return new Number(a^(b|~c))} -function mixOneRound(a,b,c,d,e,f,h,g){switch(g){case 0:a+=F(b,c,d)+f+0;break;case 1:a+=G(b,c,d)+f+1518500249;break;case 2:a+=H(b,c,d)+f+1859775393;break;case 3:a+=I(b,c,d)+f+2400959708;break;case 4:a+=J(b,c,d)+f+2840853838;break;case 5:a+=J(b,c,d)+f+1352829926;break;case 6:a+=I(b,c,d)+f+1548603684;break;case 7:a+=H(b,c,d)+f+1836072691;break;case 8:a+=G(b,c,d)+f+2053994217;break;case 9:a+=F(b,c,d)+f+0;break;default:document.write("Bogus round number")}a=ROL(a,h)+e;c=ROL(c,10);g=[];g[0]=a&4294967295; -g[1]=b&4294967295;g[2]=c&4294967295;g[3]=d&4294967295;g[4]=e&4294967295;g[5]=f;g[6]=h;return g}function MDinit(a){a[0]=1732584193;a[1]=4023233417;a[2]=2562383102;a[3]=271733878;a[4]=3285377520} -var ROLs=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]],indexes=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12, -0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]]; -function compress(a,b){blockA=[];blockB=[];for(var c,d=0;5>d;d++)blockA[d]=new Number(a[d]),blockB[d]=new Number(a[d]);for(var e=0,f=0;5>f;f++)for(d=0;16>d;d++)c=mixOneRound(blockA[(e+0)%5],blockA[(e+1)%5],blockA[(e+2)%5],blockA[(e+3)%5],blockA[(e+4)%5],b[indexes[f][d]],ROLs[f][d],f),blockA[(e+0)%5]=c[0],blockA[(e+1)%5]=c[1],blockA[(e+2)%5]=c[2],blockA[(e+3)%5]=c[3],blockA[(e+4)%5]=c[4],e+=4;e=0;for(f=5;10>f;f++)for(d=0;16>d;d++)c=mixOneRound(blockB[(e+0)%5],blockB[(e+1)%5],blockB[(e+2)%5],blockB[(e+ -3)%5],blockB[(e+4)%5],b[indexes[f][d]],ROLs[f][d],f),blockB[(e+0)%5]=c[0],blockB[(e+1)%5]=c[1],blockB[(e+2)%5]=c[2],blockB[(e+3)%5]=c[3],blockB[(e+4)%5]=c[4],e+=4;blockB[3]+=blockA[2]+a[1];a[1]=a[2]+blockA[3]+blockB[4];a[2]=a[3]+blockA[4]+blockB[0];a[3]=a[4]+blockA[0]+blockB[1];a[4]=a[0]+blockA[1]+blockB[2];a[0]=blockB[3]}function zeroX(a){for(var b=0;16>b;b++)a[b]=0} -function MDfinish(a,b,c,d){var e=Array(16);zeroX(e);for(var f=0,h=0;h<(c&63);h++)e[h>>>2]^=(b.charCodeAt(f++)&255)<<8*(h&3);e[c>>>2&15]^=1<<8*(c&3)+7;55<(c&63)&&(compress(a,e),e=Array(16),zeroX(e));e[14]=c<<3;e[15]=c>>>29|d<<3;compress(a,e)}function BYTES_TO_DWORD(a){var b=(a.charCodeAt(3)&255)<<24,b=b|(a.charCodeAt(2)&255)<<16,b=b|(a.charCodeAt(1)&255)<<8;return b|=a.charCodeAt(0)&255} -function RMD(a){var b=Array(RMDsize/32),c=Array(RMDsize/8),d,e;MDinit(b);d=a.length;var f=Array(16);zeroX(f);var h=0;for(e=d;63g;g++)f[g]=BYTES_TO_DWORD(a.substr(h,4)),h+=4;compress(b,f)}MDfinish(b,a.substr(h),d,0);for(g=0;g>>2]&255,c[g+1]=b[g>>>2]>>>8&255,c[g+2]=b[g>>>2]>>>16&255,c[g+3]=b[g>>>2]>>>24&255;return c}function RMDstring(a){for(var a=RMD(a),b="",c=0;c>>32-e,c)}function ff(a,b,c,d,e,f,h){return cmn(b&c|~b&d,a,b,e,f,h)}function gg(a,b,c,d,e,f,h){return cmn(b&d|c&~d,a,b,e,f,h)}function hh(a,b,c,d,e,f,h){return cmn(b^c^d,a,b,e,f,h)} -function ii(a,b,c,d,e,f,h){return cmn(c^(b|~d),a,b,e,f,h)}function md51(a){txt="";var b=a.length,c=[1732584193,-271733879,-1732584194,271733878],d;for(d=64;d<=a.length;d+=64)md5cycle(c,md5blk(a.substring(d-64,d)));var a=a.substring(d-64),e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(d=0;d>2]|=a.charCodeAt(d)<<(d%4<<3);e[d>>2]|=128<<(d%4<<3);if(55d;d++)e[d]=0}e[14]=8*b;md5cycle(c,e);return c} -function md5blk(a){var b=[],c;for(c=0;64>c;c+=4)b[c>>2]=a.charCodeAt(c)+(a.charCodeAt(c+1)<<8)+(a.charCodeAt(c+2)<<16)+(a.charCodeAt(c+3)<<24);return b}var hex_chr="0123456789abcdef".split("");function rhex(a){for(var b="",c=0;4>c;c++)b+=hex_chr[a>>8*c+4&15]+hex_chr[a>>8*c&15];return b}function hex(a){for(var b=0;b>16)+(b>>16)+(c>>16)<<16|c&65535}); -function openpgp_keyring(){this.init=function(){var a=JSON.parse(window.localStorage.getItem("privatekeys")),b=JSON.parse(window.localStorage.getItem("publickeys"));if(null==a||0==a.length)a=[];if(null==b||0==b.length)b=[];this.publicKeys=[];this.privateKeys=[];for(var c=0,d=0;d")[0]: -a.trim(),d=d.toLowerCase();if(!util.emailRegEx.test(d))return b;for(a=0;a")[0]:a.trim(),d=d.toLowerCase();if(!util.emailRegEx.test(d))return b;for(a=0;a -a;){var e=openpgp_packet.read_packet(b,a,b.length-a);if(null==e){util.print_error("openpgp.msg.messge decrypt:\n[pub/priv_key]parsing ends here @:"+a+" l:"+d);break}else switch(e.tagType){case 2:if(32==e.signatureType)this.revocationSignatures[this.revocationSignatures.length]=e;else if(15e.signatureType){if(null==this.certificationsignatures)this.certificationSignatures=[];this.certificationSignatures[this.certificationSignatures.length]=e}else util.print_error("openpgp.msg.messge decrypt:\nunknown signature type directly on key "+ -e.signatureType+" @"+a);a+=e.packetLength+e.headerLength;break;case 7:this.subKeys[this.subKeys.length]=e;a+=e.packetLength+e.headerLength;a+=e.read_nodes(this.privateKeyPacket,b,a,b.length-a);break;case 17:this.userAttributes[this.userAttributes.length]=e;a+=e.packetLength+e.headerLength;a+=e.read_nodes(this.privateKeyPacket,b,a,b.length-a);break;case 13:this.userIds[this.userIds.length]=e;a+=e.packetLength+e.headerLength;a+=e.read_nodes(this.privateKeyPacket,b,a,b.length-a);break;default:return this.position= -c-this.privateKeyPacket.packetLength-this.privateKeyPacket.headerLength,this.len=a-c}}this.position=c-this.privateKeyPacket.packetLength-this.privateKeyPacket.headerLength;return this.len=a-c};this.decryptSecretMPIs=function(a){return this.privateKeyPacket.decryptSecretMPIs(a)};this.getSubKeyIds=function(){if(4==this.privateKeyPacket.publicKey.version)var a=[];for(var b=0;b").text(a).html()} -function openpgp_encoding_eme_pkcs1_encode(a,b){if(a.length>b-11)return-1;var c;c=""+String.fromCharCode(0);c+=String.fromCharCode(2);for(var d=0;da.length||0!=a.charCodeAt(0)||2!=a.charCodeAt(1))return-1;for(var c=2;0!=a.charCodeAt(c)&&a.length>c;)c++;return a.substring(c+1,a.length)} +1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246];function B0(b){return b&255}function B1(b){return b>>8&255}function B2(b){return b>>16&255} +function B3(b){return b>>24&255}function F1(b,a,c,d){return B1(T1[b&255])|B1(T1[a>>8&255])<<8|B1(T1[c>>16&255])<<16|B1(T1[d>>>24])<<24}function packBytes(b){var a,c,d=b.length,e=Array(d/4);if(b&&!(d%4)){for(a=0,c=0;cc;d++,c++)f[b][c]=k[d];4==c&&(b++,c=0)}for(;bc;d++,c++)f[b][c]=k[d];4==c&&(b++,c=0)}}this.rounds=e;this.rk=f;return this} +function AESencrypt(b,a){var c,d,e,f,g,h=packBytes(b),k=a.rounds,j=h[0],l=h[1],o=h[2];g=h[3];for(c=0;c>8&255]^T3[f>>16&255]^T4[g>>>24],l=T1[e&255]^T2[f>>8&255]^T3[g>>16&255]^T4[d>>>24],o=T1[f&255]^T2[g>>8&255]^T3[d>>16&255]^T4[e>>>24],g=T1[g&255]^T2[d>>8&255]^T3[e>>16&255]^T4[f>>>24];c=k-1;d=j^a.rk[c][0];e=l^a.rk[c][1];f=o^a.rk[c][2];g^=a.rk[c][3];h[0]=F1(d,e,f,g)^a.rk[k][0];h[1]=F1(e,f,g,d)^a.rk[k][1];h[2]=F1(f, +g,d,e)^a.rk[k][2];h[3]=F1(g,d,e,f)^a.rk[k][3];return unpackBytes(h)}function TFencrypt(b,a){var c=[].concat(b),d=createTwofish();d.open(util.str2bin(a),0);c=d.encrypt(c,0);d.close();return c}var MAXINT=4294967295;function rotb(b,a){return(b<>>8-a)&255}function rotw(b,a){return(b<>>32-a)&MAXINT}function getW(b,a){return b[a]|b[a+1]<<8|b[a+2]<<16|b[a+3]<<24}function setW(b,a,c){b.splice(a,4,c&255,c>>>8&255,c>>>16&255,c>>>24&255)} +function setWInv(b,a,c){b.splice(a,4,c>>>24&255,c>>>16&255,c>>>8&255,c&255)}function getB(b,a){return b>>>8*a&255}function getNrBits(b){for(var a=0;0>>=1;return a}function getMask(b){return(1<d;d++)e=c>>>24,c=c<<8&MAXINT|a>>>24,a=a<<8&MAXINT,f=e<<1,e&128&&(f^=333),c^=e^f<<16,f^=e>>>1,e&1&&(f^=166),c^=f<<24|f<<8;return c}function d(a,b){var c,e,f;c=b>>4;e=b&15;f=t[a][c^ +e];c=E[a][M[e]^K[c]];return D[a][M[c]^K[f]]<<4|Q[a][f^c]}function e(a,b){var c=getB(a,0),d=getB(a,1),f=getB(a,2),g=getB(a,3);switch(x){case 4:c=w[1][c]^getB(b[3],0),d=w[0][d]^getB(b[3],1),f=w[0][f]^getB(b[3],2),g=w[1][g]^getB(b[3],3);case 3:c=w[1][c]^getB(b[2],0),d=w[1][d]^getB(b[2],1),f=w[0][f]^getB(b[2],2),g=w[0][g]^getB(b[2],3);case 2:c=w[0][w[0][c]^getB(b[1],0)]^getB(b[0],0),d=w[0][w[1][d]^getB(b[1],1)]^getB(b[0],1),f=w[1][w[0][f]^getB(b[1],2)]^getB(b[0],2),g=w[1][w[1][g]^getB(b[1],3)]^getB(b[0], +3)}return z[0][c]^z[1][d]^z[2][f]^z[3][g]}c=a;var o,r,p,m;p=[];m=[];var y=[],x,v=[],u,t=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],E=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],Q=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],D=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],M=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],K=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14, +7],w=[[],[]],z=[[],[],[],[]];c=c.slice(0,32);for(a=c.length;16!=a&&24!=a&&32!=a;)c[a++]=0;for(a=0;a>2]=getW(c,a);for(a=0;256>a;a++)w[0][a]=d(0,a),w[1][a]=d(1,a);for(a=0;256>a;a++)o=w[1][a],r=o^o>>2^[0,90,180,238][o&3],u=o^o>>1^o>>2^[0,238,180,90][o&3],z[0][a]=o+(r<<8)+(u<<16)+(u<<24),z[2][a]=r+(u<<8)+(o<<16)+(u<<24),o=w[0][a],r=o^o>>2^[0,90,180,238][o&3],u=o^o>>1^o>>2^[0,238,180,90][o&3],z[1][a]=u+(u<<8)+(r<<16)+(o<<24),z[3][a]=r+(o<<8)+(u<<16)+(r<<24);x=y.length/2;for(a=0;aa;a+=2)o=16843009*a,r=o+16843009,o=e(o,p),r=rotw(e(r,m),8),f[a]=o+r&MAXINT,f[a+1]=rotw(o+2*r,9);for(a=0;256>a;a++)switch(o=r=p=m=a,x){case 4:o=w[1][o]^getB(v[3],0),r=w[0][r]^getB(v[3],1),p=w[0][p]^getB(v[3],2),m=w[1][m]^getB(v[3],3);case 3:o=w[1][o]^getB(v[2],0),r=w[1][r]^getB(v[2],1),p=w[0][p]^getB(v[2],2),m=w[0][m]^getB(v[2],3);case 2:g[0][a]=z[0][w[0][w[0][o]^getB(v[1],0)]^getB(v[0],0)],g[1][a]=z[1][w[0][w[1][r]^getB(v[1],1)]^getB(v[0], +1)],g[2][a]=z[2][w[1][w[0][p]^getB(v[1],2)]^getB(v[0],2)],g[3][a]=z[3][w[1][w[1][m]^getB(v[1],3)]^getB(v[0],3)]}},close:function(){f=[];g=[[],[],[],[]]},encrypt:function(c,g){d=c;e=g;for(var j=[getW(d,e)^f[0],getW(d,e+4)^f[1],getW(d,e+8)^f[2],getW(d,e+12)^f[3]],l=0;8>l;l++){var o=l,r=j,p=b(r[0]),m=a(r[1]);r[2]=rotw(r[2]^p+m+f[4*o+8]&MAXINT,31);r[3]=rotw(r[3],1)^p+2*m+f[4*o+9]&MAXINT;p=b(r[2]);m=a(r[3]);r[0]=rotw(r[0]^p+m+f[4*o+10]&MAXINT,31);r[1]=rotw(r[1],1)^p+2*m+f[4*o+11]&MAXINT}setW(d,e,j[2]^ +f[4]);setW(d,e+4,j[3]^f[5]);setW(d,e+8,j[0]^f[6]);setW(d,e+12,j[1]^f[7]);e+=16;return d},decrypt:function(c,g){d=c;e=g;for(var j=[getW(d,e)^f[4],getW(d,e+4)^f[5],getW(d,e+8)^f[6],getW(d,e+12)^f[7]],l=7;0<=l;l--){var o=l,r=j,p=b(r[0]),m=a(r[1]);r[2]=rotw(r[2],1)^p+m+f[4*o+10]&MAXINT;r[3]=rotw(r[3]^p+2*m+f[4*o+11]&MAXINT,31);p=b(r[2]);m=a(r[3]);r[0]=rotw(r[0],1)^p+m+f[4*o+8]&MAXINT;r[1]=rotw(r[1]^p+2*m+f[4*o+9]&MAXINT,31)}setW(d,e,j[2]^f[0]);setW(d,e+4,j[3]^f[1]);setW(d,e+8,j[0]^f[2]);setW(d,e+12,j[1]^ +f[3]);e+=16},finalize:function(){return d}}}function SecureRandom(){this.nextBytes=function(b){for(var a=0;a>1;d.e=parseInt(c,16);for(d.ee=new BigInteger(c,16);;){for(;!(d.p=new BigInteger(a-f,1,e),0==d.p.subtract(BigInteger.ONE).gcd(d.ee).compareTo(BigInteger.ONE)&&d.p.isProbablePrime(10)););for(;!(d.q=new BigInteger(f,1,e),0==d.q.subtract(BigInteger.ONE).gcd(d.ee).compareTo(BigInteger.ONE)&&d.q.isProbablePrime(10));); +if(0>=d.p.compareTo(d.q)){var g=d.p;d.p=d.q;d.q=g}var g=d.p.subtract(BigInteger.ONE),h=d.q.subtract(BigInteger.ONE),k=g.multiply(h);if(0==k.gcd(d.ee).compareTo(BigInteger.ONE)){d.n=d.p.multiply(d.q);d.d=d.ee.modInverse(k);d.dmp1=d.d.mod(g);d.dmq1=d.d.mod(h);d.u=d.p.modInverse(d.q);break}}return d};this.keyObject=b} +function DSA(){this.select_hash_algorithm=function(b){var a=openpgp.config.config.prefer_hash_algorithm;switch(Math.round(b.bitLength()/8)){case 20:return 2!=a&&11a?2:a;case 28:return 11a?11:a;case 32:return 10a?8:a;default:return util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}};this.sign=function(b,a,c,d,e,f){b=util.getLeftNBits(openpgp_crypto_hashData(b,a),e.bitLength());b=new BigInteger(util.hexstrdump(b),16);a=openpgp_crypto_getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), +e.subtract(BigInteger.ONE));c=c.modPow(a,d).mod(e);e=a.modInverse(e).multiply(b.add(f.multiply(c))).mod(e);f=[];f[0]=c.toMPI();f[1]=e.toMPI();return f};this.verify=function(b,a,c,d,e,f,g,h){b=util.getLeftNBits(openpgp_crypto_hashData(b,d),f.bitLength());b=new BigInteger(util.hexstrdump(b),16);if(0>15;0<=--f;){var h=this[b]&32767,k=this[b++]>>15,j=a*h+k*g,h=g*h+((j&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(j>>>15)+a*k+(e>>>30);c[d++]=h&1073741823}return e}function am3(b,a,c,d,e,f){for(var g=a&16383,a=a>>14;0<=--f;){var h=this[b]&16383,k=this[b++]>>14,j=a*h+k*g,h=g*h+((j&16383)<<14)+c[d]+e,e=(h>>28)+(j>>14)+a*k;c[d++]=h&268435455}return e} +j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(b){return BI_RM.charAt(b)}function intAt(b,a){var c=BI_RC[b.charCodeAt(a)];return null==c?-1:c}function bnpCopyTo(b){for(var a=this.t-1;0<=a;--a)b[a]=this[a];b.t=this.t;b.s=this.s}function bnpFromInt(b){this.t=1;this.s=0>b?-1:0;0b?this[0]=b+DV:this.t=0}function nbv(b){var a=nbi();a.fromInt(b);return a} +function bnpFromString(b,a){var c;if(16==a)c=4;else if(8==a)c=3;else if(256==a)c=8;else if(2==a)c=1;else if(32==a)c=5;else if(4==a)c=2;else{this.fromRadix(b,a);return}this.s=this.t=0;for(var d=b.length,e=!1,f=0;0<=--d;){var g=8==c?b[d]&255:intAt(b,d);0>g?"-"==b.charAt(d)&&(e=!0):(e=!1,0==f?this[this.t++]=g:f+c>this.DB?(this[this.t-1]|=(g&(1<>this.DB-f):this[this.t-1]|=g<=this.DB&&(f-=this.DB))}if(8==c&&0!=(b[0]&128))this.s=-1,0this.s)return"-"+this.negate().toString(b);if(16==b)b=4;else if(8==b)b=3;else if(2==b)b=1;else if(32==b)b=5;else if(4==b)b=2;else return this.toRadix(b);var a=(1<>g))d=!0,e=int2char(c);for(;0<=f;)g>(g+=this.DB-b)):(c=this[f]>>(g-=b)&a,0>=g&&(g+=this.DB,--f)),0this.s?this.negate():this}function bnCompareTo(b){var a=this.s-b.s;if(0!=a)return a;var c=this.t,a=c-b.t;if(0!=a)return a;for(;0<=--c;)if(0!=(a=this[c]-b[c]))return a;return 0}function nbits(b){var a=1,c;if(0!=(c=b>>>16))b=c,a+=16;if(0!=(c=b>>8))b=c,a+=8;if(0!=(c=b>>4))b=c,a+=4;if(0!=(c=b>>2))b=c,a+=2;0!=b>>1&&(a+=1);return a} +function bnBitLength(){return 0>=this.t?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(b,a){var c;for(c=this.t-1;0<=c;--c)a[c+b]=this[c];for(c=b-1;0<=c;--c)a[c]=0;a.t=this.t+b;a.s=this.s}function bnpDRShiftTo(b,a){for(var c=b;c>d|g,g=(this[h]&e)<=this.t)a.t=0;else{var d=b%this.DB,e=this.DB-d,f=(1<>d;for(var g=c+1;g>d;0>=this.DB;if(b.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=b.s}a.s=0>d?-1:0;-1>d?a[c++]=this.DV+d:0=a.DV)b[c+a.t]-=a.DV,b[c+a.t+1]=1}0=d.t)){var e=this.abs();if(e.t>this.F2:0),j=this.FV/k,k=(1<g&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(b){var a=nbi();this.abs().divRemTo(b,null,a);0>this.s&&0b.s||0<=b.compareTo(this.m)?b.mod(this.m):b}function cRevert(b){return b}function cReduce(b){b.divRemTo(this.m,null,b)}function cMulTo(b,a,c){b.multiplyTo(a,c);this.reduce(c)}function cSqrTo(b,a){b.squareTo(a);this.reduce(a)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo; +function bnpInvDigit(){if(1>this.t)return 0;var b=this[0];if(0==(b&1))return 0;var a=b&3,a=a*(2-(b&15)*a)&15,a=a*(2-(b&255)*a)&255,a=a*(2-((b&65535)*a&65535))&65535,a=a*(2-b*a%this.DV)%this.DV;return 0>15;this.um=(1<b.s&&0>15)*this.mpl&this.um)<<15)&b.DM,c=a+this.m.t;for(b[c]+=this.m.am(0,d,b,a,0,this.m.t);b[c]>=b.DV;)b[c]-=b.DV,b[++c]++}b.clamp();b.drShiftTo(this.m.t,b);0<=b.compareTo(this.m)&&b.subTo(this.m,b)}function montSqrTo(b,a){b.squareTo(a);this.reduce(a)}function montMulTo(b,a,c){b.multiplyTo(a,c);this.reduce(c)}Montgomery.prototype.convert=montConvert; +Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return 0==(0b)return BigInteger.ONE;var c=nbi(),d=nbi(),e=a.convert(this),f=nbits(b)-1;for(e.copyTo(c);0<=--f;)if(a.sqrTo(c,d),0<(b&1<b||a.isEven()?new Classic(a):new Montgomery(a);return this.exp(b,c)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo; +BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt; +BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1); +function Elgamal(){this.encrypt=function(b,a,c,d){var e=BigInteger.ONE.add(BigInteger.ONE),f=c.subtract(e),e=openpgp_crypto_getRandomBigIntegerInRange(e,f),e=e.mod(f).add(BigInteger.ONE),f=[];f[0]=a.modPow(e,c);f[1]=d.modPow(e,c).multiply(b).mod(c).toMPI();f[0]=f[0].toMPI();return f};this.decrypt=function(b,a,c,d){util.print_debug("Elgamal Decrypt:\nc1:"+util.hexstrdump(b.toMPI())+"\nc2:"+util.hexstrdump(a.toMPI())+"\np:"+util.hexstrdump(c.toMPI())+"\nx:"+util.hexstrdump(d.toMPI()));return b.modPow(d, +c).modInverse(c).multiply(a).mod(c)}}function bnClone(){var b=nbi();this.copyTo(b);return b}function bnIntValue(){if(0>this.s){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function bnShortValue(){return 0==this.t?this.s:this[0]<<16>>16}function bnpChunkSize(b){return Math.floor(Math.LN2*this.DB/Math.log(b))} +function bnSigNum(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function bnpToRadix(b){null==b&&(b=10);if(0==this.signum()||2>b||36k?"-"==b.charAt(h)&&0==this.signum()&&(e=!0):(g=a*g+k,++f>=c&&(this.dMultiply(d),this.dAddOffset(g,0),g=f=0))}0b)this.fromInt(1);else{this.fromNumber(b,c);this.testBit(b-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(b-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(a);)this.dAddOffset(2,0),this.bitLength()>b&&this.subTo(BigInteger.ONE.shiftLeft(b-1),this)}else{var c=[],d=b&7;c.length=(b>>3)+1;a.nextBytes(c);c[0]=0>c)!=(this.s&this.DM)>>c)a[e++]=d|this.s<c?(d=(this[b]&(1<>(c+=this.DB-8)):(d=this[b]>>(c-=8)&255,0>=c&&(c+=this.DB,--b)),0this.compareTo(b)?this:b}function bnMax(b){return 0b?this.rShiftTo(-b,a):this.lShiftTo(b,a);return a}function bnShiftRight(b){var a=nbi();0>b?this.lShiftTo(-b,a):this.rShiftTo(b,a);return a} +function lbit(b){if(0==b)return-1;var a=0;0==(b&65535)&&(b>>=16,a+=16);0==(b&255)&&(b>>=8,a+=8);0==(b&15)&&(b>>=4,a+=4);0==(b&3)&&(b>>=2,a+=2);0==(b&1)&&++a;return a}function bnGetLowestSetBit(){for(var b=0;bthis.s?this.t*this.DB:-1}function cbit(b){for(var a=0;0!=b;)b&=b-1,++a;return a}function bnBitCount(){for(var b=0,a=this.s&this.DM,c=0;c=this.t?0!=this.s:0!=(this[a]&1<>=this.DB;if(b.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=b.s}a.s=0>d?-1:0;0d&&(a[c++]=this.DV+d);a.t=c;a.clamp()}function bnAdd(b){var a=nbi();this.addTo(b,a);return a}function bnSubtract(b){var a=nbi();this.subTo(b,a);return a} +function bnMultiply(b){var a=nbi();this.multiplyTo(b,a);return a}function bnSquare(){var b=nbi();this.squareTo(b);return b}function bnDivide(b){var a=nbi();this.divRemTo(b,a,null);return a}function bnRemainder(b){var a=nbi();this.divRemTo(b,null,a);return a}function bnDivideAndRemainder(b){var a=nbi(),c=nbi();this.divRemTo(b,a,c);return[a,c]}function bnpDMultiply(b){this[this.t]=this.am(0,b-1,this,0,0,this.t);++this.t;this.clamp()} +function bnpDAddOffset(b,a){if(0!=b){for(;this.t<=a;)this[this.t++]=0;for(this[a]+=b;this[a]>=this.DV;)this[a]-=this.DV,++a>=this.t&&(this[this.t++]=0),++this[a]}}function NullExp(){}function nNop(b){return b}function nMulTo(b,a,c){b.multiplyTo(a,c)}function nSqrTo(b,a){b.squareTo(a)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(b){return this.exp(b,new NullExp)} +function bnpMultiplyLowerTo(b,a,c){var d=Math.min(this.t+b.t,a);c.s=0;for(c.t=d;0b.s||b.t>2*this.m.t)return b.mod(this.m);if(0>b.compareTo(this.m))return b;var a=nbi();b.copyTo(a);this.reduce(a);return a}function barrettRevert(b){return b} +function barrettReduce(b){b.drShiftTo(this.m.t-1,this.r2);if(b.t>this.m.t+1)b.t=this.m.t+1,b.clamp();this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>b.compareTo(this.r2);)b.dAddOffset(1,this.m.t+1);for(b.subTo(this.r2,b);0<=b.compareTo(this.m);)b.subTo(this.m,b)}function barrettSqrTo(b,a){b.squareTo(a);this.reduce(a)}function barrettMulTo(b,a,c){b.multiplyTo(a,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert; +Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo; +function bnModPow(b,a){var c=b.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(a):a.isEven()?new Barrett(a):new Montgomery(a);var g=[],h=3,k=d-1,j=(1<=k?o=b[l]>>c-k&j:(o=(b[l]&(1<>this.DB+c-k));for(h=d;0==(o&1);)o>>=1,--h;if(0>(c-=h))c+=this.DB,--l;if(r)g[o].copyTo(e), +r=!1;else{for(;1--c&&(c=this.DB-1,--l)}return f.revert(e)} +function bnGCD(b){var a=0>this.s?this.negate():this.clone(),b=0>b.s?b.negate():b.clone();if(0>a.compareTo(b))var c=a,a=b,b=c;var c=a.getLowestSetBit(),d=b.getLowestSetBit();if(0>d)return a;c=b)return 0;var a=this.DV%b,c=0>this.s?b-1:0;if(0h.signum())h.addTo(b,h);else return h;return 0>h.signum()?h.add(b):h} +var lowprimes=[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,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727, +733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],lplim=67108864/lowprimes[lowprimes.length-1]; +function bnIsProbablePrime(b){var a,c=this.abs();if(1==c.t&&c[0]<=lowprimes[lowprimes.length-1]){for(a=0;a>>16))b=c,a+=16;if(0!=(c=b>>8))b=c,a+=8;if(0!=(c=b>>4))b=c,a+=4;if(0!=(c=b>>2))b=c,a+=2;0!=b>>1&&(a+=1);return a}function bnToMPI(){var b=this.toByteArray(),a=8*(b.length-1)+nbits(b[0]),c;c=""+String.fromCharCode((a&65280)>>8);c+=String.fromCharCode(a&255);return c+=util.bin2str(b)} +function bnpMillerRabin(b){var a=this.subtract(BigInteger.ONE),c=a.getLowestSetBit();if(0>=c)return!1;var d=a.shiftRight(c),b=b+1>>1;if(b>lowprimes.length)b=lowprimes.length;for(var e=nbi(),f=0;fa*g;){for(var e=b(f,c),f=d.substring(g*a,g*a+a),j=0;ja*g;){for(var k=b(f,c),f=d.substring(g*a+0,g*a+a+0),e=0;ea-b;)window.crypto.getRandomValues(c);return b+Math.abs(c[0]&Math.pow(2,d)-1)}function openpgp_crypto_getSecureRandomOctet(){var b=new Uint32Array(1);window.crypto.getRandomValues(b);return b[0]&255} +function openpgp_crypto_getRandomBigInteger(b){if(0>b)return null;var a=openpgp_crypto_getRandomBytes(Math.floor((b+7)/8));0=a.compareTo(b))){for(var c=a.subtract(b),d=openpgp_crypto_getRandomBigInteger(c.bitLength());d>c;)d=openpgp_crypto_getRandomBigInteger(c.bitLength());return b.add(d)}} +function openpgp_crypto_testRSA(b){debugger;var a=new RSA,c=new openpgp_type_mpi;c.create(openpgp_encoding_eme_pkcs1_encode("ABABABAB",128));c=a.encrypt(c.toBigInteger(),b.ee,b.n);a.decrypt(c,b.d,b.p,b.q,b.u)} +function openpgp_crypto_generateKeyPair(b,a,c,d,e){var f,g,h=new Date,h=h.getTime()/1E3,h=String.fromCharCode(Math.floor(h/16777216%256))+String.fromCharCode(Math.floor(h/65536%256))+String.fromCharCode(Math.floor(h/256%256))+String.fromCharCode(Math.floor(h%256));switch(b){case 1:a=(new RSA).generate(a,"10001");f=(new openpgp_packet_keymaterial).write_private_key(b,a,c,d,e,h);g=(new openpgp_packet_keymaterial).write_public_key(b,a,h);break;default:util.print_error("Unknown keytype "+b)}return{privateKey:f, +publicKey:g}} +function _openpgp(){this.tostring="";this.generate_key_pair=function(b,a,c,d){var e=(new openpgp_packet_userid).write_packet(c),a=openpgp_crypto_generateKeyPair(b,a,d,openpgp.config.config.prefer_hash_algorithm,3),b=a.privateKey,f=(new openpgp_packet_keymaterial).read_priv_key(b.string,3,b.string.length);f.decryptSecretMPIs(d)||util.print_error("Issue creating key. Unable to read resulting private key");d=new openpgp_msg_privatekey;d.privateKeyPacket=f;d.getPreferredSignatureHashAlgorithm=function(){return openpgp.config.config.prefer_hash_algorithm}; +f=d.privateKeyPacket.publicKey.data;f=String.fromCharCode(153)+String.fromCharCode(f.length>>8&255)+String.fromCharCode(f.length&255)+f+String.fromCharCode(180)+String.fromCharCode(c.length>>24)+String.fromCharCode(c.length>>16&255)+String.fromCharCode(c.length>>8&255)+String.fromCharCode(c.length&255)+c;c=new openpgp_packet_signature;c=c.write_message_signature(16,f,d);a=openpgp_encoding_armor(4,a.publicKey.string+e+c.openpgp);e=openpgp_encoding_armor(5,b.string+e+c.openpgp);return{privateKey:d, +privateKeyArmored:e,publicKeyArmored:a}};this.write_signed_message=function(b,a){var c=(new openpgp_packet_signature).write_message_signature(1,a.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),b),c={text:a.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),openpgp:c.openpgp,hash:c.hash};return openpgp_encoding_armor(2,c,null,null)};this.write_signed_and_encrypted_message=function(b,a,c){var d="",e=(new openpgp_packet_literaldata).write_packet(c.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"));util.print_debug_hexstr_dump("literal_packet: |"+ +e+"|\n",e);for(var f=0;fh.signatureType||3==h.tagType||8==h.tagType||9==h.tagType||10==h.tagType||11==h.tagType||18==h.tagType||19==h.tagType)if(d[d.length]=new openpgp_msg_message,d[e].messagePacket=h,d[e].type=a.type,9==h.tagType||1==h.tagType||3==h.tagType||18==h.tagType)if(9==h.tagType){util.print_error("unexpected openpgp packet");break}else if(1==h.tagType){util.print_debug("session key found:\n "+ +h.toString());var k=!0;d[e].sessionKeys=[];for(var j=0;k;)d[e].sessionKeys[j]=h,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength,h=openpgp_packet.read_packet(b,f,g),1!=h.tagType&&3!=h.tagType&&(k=!1),j++;18==h.tagType||9==h.tagType?(util.print_debug("encrypted data found:\n "+h.toString()),d[e].encryptedData=h,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength,e++):util.print_debug("something is wrong: "+h.tagType)}else{if(18==h.tagType){util.print_debug("symmetric encrypted data"); +break}}else if(2==h.tagType&&3>h.signatureType){d[e].text=a.text;d[e].signature=h;break}else if(8==h.tagType){util.print_error("A directly compressed message is currently not supported");break}else if(10==h.tagType)d.length=0,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength;else{if(11==h.tagType){util.print_error("A direct literal message is currently not supported.");break}}else return util.print_error("no message found!"),null}return d};this.read_publicKey=function(b){for(var a= +0,c=[],d=0,b=openpgp_encoding_deArmor(b.replace(/\r/g,"")).openpgp,e=b.length;a!=b.length;){var f=openpgp_packet.read_packet(b,a,e);if(153==b[a].charCodeAt()||6==f.tagType)c[d]=new openpgp_msg_publickey,c[d].header=b.substring(a,a+3),153==b[a].charCodeAt()?(a++,e=b[a++].charCodeAt()<<8|b[a++].charCodeAt(),c[d].publicKeyPacket=new openpgp_packet_keymaterial,c[d].publicKeyPacket.header=c[d].header,c[d].publicKeyPacket.read_tag6(b,a,e),a+=c[d].publicKeyPacket.packetLength,a+=c[d].read_nodes(c[d].publicKeyPacket, +b,a,b.length-a)):(c[d]=new openpgp_msg_publickey,c[d].publicKeyPacket=f,a+=f.headerLength+f.packetLength,a+=c[d].read_nodes(f,b,a,b.length-a));else return util.print_error("no public key found!"),null;c[d].data=b.substring(0,a);d++}return c};this.read_privateKey=function(b){for(var a=[],c=0,d=0,b=openpgp_encoding_deArmor(b.replace(/\r/g,"")).openpgp,e=b.length;d!=b.length;){var f=openpgp_packet.read_packet(b,d,e);if(5==f.tagType)a[a.length]=new openpgp_msg_privatekey,d+=f.headerLength+f.packetLength, +d+=a[c].read_nodes(f,b,d,e);else return util.print_error("no block packet found!"),null;a[c].data=b.substring(0,d);c++}return a};this.init=function(){this.config=new openpgp_config;this.config.read();this.keyring=new openpgp_keyring;this.keyring.init()}}var openpgp=new _openpgp; +function openpgp_msg_publickey(){this.tostring="OPENPGP PUBLIC KEY\n";this.publicKeyPacket=this.bindingSignature=null;this.userIds=[];this.userAttributes=[];this.revocationSignatures=[];this.subKeys=[];this.arbitraryPacket=[];this.directSignatures=[];this.verifyCertificationSignatures=function(){for(var b=[],a=0;a +b;){var e=openpgp_packet.read_packet(a,b,a.length-b);if(null==e){util.print_error("openpgp.msg.messge decrypt:\n[pub/priv_key]parsing ends here @:"+b+" l:"+d);break}else switch(e.tagType){case 2:if(32==e.signatureType)this.revocationSignatures[this.revocationSignatures.length]=e;else if(15e.signatureType){if(null==this.certificationsignatures)this.certificationSignatures=[];this.certificationSignatures[this.certificationSignatures.length]=e}else util.print_error("openpgp.msg.messge decrypt:\nunknown signature type directly on key "+ +e.signatureType+" @"+b);b+=e.packetLength+e.headerLength;break;case 7:this.subKeys[this.subKeys.length]=e;b+=e.packetLength+e.headerLength;b+=e.read_nodes(this.privateKeyPacket,a,b,a.length-b);break;case 17:this.userAttributes[this.userAttributes.length]=e;b+=e.packetLength+e.headerLength;b+=e.read_nodes(this.privateKeyPacket,a,b,a.length-b);break;case 13:this.userIds[this.userIds.length]=e;b+=e.packetLength+e.headerLength;b+=e.read_nodes(this.privateKeyPacket,a,b,a.length-b);break;default:return this.position= +c-this.privateKeyPacket.packetLength-this.privateKeyPacket.headerLength,this.len=b-c}}this.position=c-this.privateKeyPacket.packetLength-this.privateKeyPacket.headerLength;return this.len=b-c};this.decryptSecretMPIs=function(b){return this.privateKeyPacket.decryptSecretMPIs(b)};this.getSubKeyIds=function(){if(4==this.privateKeyPacket.publicKey.version)var b=[];for(var a=0;a").text(b).html()} +function openpgp_encoding_eme_pkcs1_encode(b,a){if(b.length>a-11)return-1;var c;c=""+String.fromCharCode(0);c+=String.fromCharCode(2);for(var d=0;db.length||0!=b.charCodeAt(0)||2!=b.charCodeAt(1))return-1;for(var c=2;0!=b.charCodeAt(c)&&b.length>c;)c++;return b.substring(c+1,b.length)} hash_headers=[,[48,32,48,12,6,8,42,134,72,134,247,13,2,5,5,0,4,16],[48,33,48,9,6,5,43,14,3,2,26,5,0,4,20],[48,33,48,9,6,5,43,36,3,2,1,5,0,4,20]];hash_headers[8]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,1,5,0,4,32];hash_headers[9]=[48,65,48,13,6,9,96,134,72,1,101,3,4,2,2,5,0,4,48];hash_headers[10]=[48,81,48,13,6,9,96,134,72,1,101,3,4,2,3,5,0,4,64];hash_headers[11]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,4,5,0,4,28]; -function openpgp_encoding_emsa_pkcs1_encode(a,b,c){var d;d=""+String.fromCharCode(0);d+=String.fromCharCode(1);for(var e=0;e>2&63),b=(c&3)<<4):1==h?(e+=b64s.charAt(b|c>>4&15),b=(c&15)<<2):2==h&&(e+=b64s.charAt(b|c>>6&3),f+=1,0==f%60&&(e+="\n"),e+=b64s.charAt(c&63)),f+=1,0==f%60&&(e+="\n"),h+=1,3==h&&(h=0);0>6-e&255)),e=e+2&7,f=b<>16)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255);return openpgp_encoding_base64_encode(a)}function verifyCheckSum(a,b){var c=getCheckSum(a);return c[0]==b[0]&&c[1]==b[1]&&c[2]==b[2]} +function openpgp_encoding_emsa_pkcs1_encode(b,a,c){var d;d=""+String.fromCharCode(0);d+=String.fromCharCode(1);for(var e=0;e>2&63),a=(c&3)<<4):1==g?(e+=b64s.charAt(a|c>>4&15),a=(c&15)<<2):2==g&&(e+=b64s.charAt(a|c>>6&3),f+=1,0==f%60&&(e+="\n"),e+=b64s.charAt(c&63)),f+=1,0==f%60&&(e+="\n"),g+=1,3==g&&(g=0);0>6-e&255)),e=e+2&7,f=a<>16)+String.fromCharCode(b>>8&255)+String.fromCharCode(b&255);return openpgp_encoding_base64_encode(b)}function verifyCheckSum(b,a){var c=getCheckSum(b);return c[0]==a[0]&&c[1]==a[1]&&c[2]==a[2]} var crc_table=[0,8801531,25875725,17603062,60024545,51751450,35206124,44007191,128024889,120049090,103502900,112007375,70412248,78916387,95990485,88014382,264588937,256049778,240098180,248108927,207005800,215016595,232553829,224014750,140824496,149062475,166599357,157832774,200747345,191980970,176028764,184266919,520933865,529177874,512099556,503334943,480196360,471432179,487973381,496217854,414011600,405478443,422020573,430033190,457094705,465107658,448029500,439496647,281648992,273666971,289622637, 298124950,324696449,333198714,315665548,307683447,392699481,401494690,383961940,375687087,352057528,343782467,359738805,368533838,1041867730,1050668841,1066628831,1058355748,1032471859,1024199112,1006669886,1015471301,968368875,960392720,942864358,951368477,975946762,984451313,1000411399,992435708,836562267,828023200,810956886,818967725,844041146,852051777,868605623,860066380,914189410,922427545,938981743,930215316,904825475,896059E3,878993294,887231349,555053627,563297984,547333942,538569677,579245274, 570480673,588005847,596249900,649392898,640860153,658384399,666397428,623318499,631331096,615366894,606833685,785398962,777416777,794487231,802989380,759421523,767923880,751374174,743392165,695319947,704115056,687564934,679289981,719477610,711202705,728272487,737067676,2083735460,2092239711,2109313705,2101337682,2141233477,2133257662,2116711496,2125215923,2073216669,2064943718,2048398224,2057199467,2013339772,2022141063,2039215473,2030942602,1945504045,1936737750,1920785440,1929023707,1885728716, 1893966647,1911503553,1902736954,1951893524,1959904495,1977441561,1968902626,2009362165,2000822798,1984871416,1992881923,1665111629,1673124534,1656046400,1647513531,1621913772,1613380695,1629922721,1637935450,1688082292,1679317903,1695859321,1704103554,1728967061,1737211246,1720132760,1711368291,1828378820,1820103743,1836060105,1844855090,1869168165,1877963486,1860430632,1852155859,1801148925,1809650950,1792118E3,1784135691,1757986588,1750004711,1765960209,1774462698,1110107254,1118611597,1134571899, 1126595968,1102643863,1094667884,1077139354,1085643617,1166763343,1158490548,1140961346,1149762745,1176011694,1184812885,1200772771,1192499800,1307552511,1298785796,1281720306,1289958153,1316768798,1325007077,1341561107,1332794856,1246636998,1254647613,1271201483,1262662192,1239272743,1230733788,1213667370,1221678289,1562785183,1570797924,1554833554,1546300521,1588974462,1580441477,1597965939,1605978760,1518843046,1510078557,1527603627,1535847760,1494504007,1502748348,1486784330,1478020017,1390639894, 1382365165,1399434779,1408230112,1366334967,1375129868,1358579962,1350304769,1430452783,1438955220,1422405410,1414423513,1456544974,1448562741,1465633219,1474135352]; -function createcrc24(a){for(var b=11994318,c=0;16>16^a.charCodeAt(c))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+1))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+2))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+3))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+4))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+5))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+6))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+7))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+8))&255],b=b<<8^crc_table[(b>> -16^a.charCodeAt(c+9))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+10))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+11))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+12))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+13))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+14))&255],b=b<<8^crc_table[(b>>16^a.charCodeAt(c+15))&255],c+=16;for(var d=c;d>16^a.charCodeAt(c++))&255];return b&16777215}; +function createcrc24(b){for(var a=11994318,c=0;16>16^b.charCodeAt(c))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+1))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+2))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+3))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+4))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+5))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+6))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+7))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+8))&255],a=a<<8^crc_table[(a>> +16^b.charCodeAt(c+9))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+10))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+11))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+12))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+13))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+14))&255],a=a<<8^crc_table[(a>>16^b.charCodeAt(c+15))&255],c+=16;for(var d=c;d>16^b.charCodeAt(c++))&255];return a&16777215}JXG={exists:function(b){return function(a){return!(a===b||null===a)}}()}; +JXG.decompress=function(b){return unescape((new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(b))).unzip()[0][0])};JXG.Util={}; +JXG.Util.Unzip=function(b){function a(){aa+=8;return B>=1;0==C&&(C=a(),b=C&1,C=C>>1|128);return b}function d(a){for(var b=0,d=a;d--;)b=b<<1|c();a&&(b=D[b]>>8-a);return b}function e(a){Q++;u[t++]=a;p.push(String.fromCharCode(a));32768==t&&(t=0)}function f(){this.b1=this.b0=0;this.jump=null;this.jumppos=-1}function g(){for(;;){if(W[N]>=ra)return-1;if(qa[W[N]]==N)return W[N]++;W[N]++}}function h(){var a=V[U],b;m&&document.write("
len:"+N+" treepos:"+ +U);if(17==N)return-1;U++;N++;b=g();m&&document.write("
IsPat "+b);if(0<=b)a.b0=b,m&&document.write("
b0 "+a.b0);else if(a.b0=32768,m&&document.write("
b0 "+a.b0),h())return-1;b=g();if(0<=b)a.b1=b,m&&document.write("
b1 "+a.b1),a.jump=null;else if(a.b1=32768,m&&document.write("
b1 "+a.b1),a.jump=V[U],a.jumppos=U,h())return-1;N--;return 0}function k(a,b,c,d){m&&document.write("currentTree "+a+" numval "+b+" lengths "+c+" show "+d);V=a;U=0;qa=c;ra=b;for(a=0;17>a;a++)W[a]=0;N=0;if(h())return m&& +alert("invalid huffman tree\n"),-1;if(m){document.write("
Tree: "+V.length);for(a=0;32>a;a++)document.write("Places["+a+"].b0="+V[a].b0+"
"),document.write("Places["+a+"].b1="+V[a].b1+"
")}return 0}function j(a){for(var b,d,e=0,f=a[e];;)if(b=c(),m&&document.write("b="+b),b){if(!(f.b1&32768))return m&&document.write("ret1"),f.b1;f=f.jump;b=a.length;for(d=0;d>1,23h)e(h);else if(256==h)break;else{var o;h-=257;p=d(K[h])+M[h];h=D[d(5)]>>3;8h;h++)r[h]=0;for(h=0;hdistanceTree");for(h=0;h"+P[h].b0+" "+P[h].b1+" "+P[h].jump+" "+P[h].jumppos)}p=g+o;l=0;var v= +-1;for(m&&document.write("
n="+p+" bits: "+aa+"
");l"+v+" i:"+l+" decode: "+h+" bits "+aa+"
"),16>h)r[l++]=h;else if(16==h){var x;h=3+d(2);if(l+h>p)return t=0,1;for(x=l?r[l-1]:0;h--;)r[l++]=x}else{h=17==h?3+d(3):11+d(7);if(l+h>p)return t=0,1;for(;h--;)r[l++]=0}p=ba.length;for(l=0;lliteralTree");;)if(h= +j(ba),256<=h){h-=256;if(0==h)break;h--;p=d(K[h])+M[h];h=j(P);8>2,c=(c&3)<<4|d>>4,g=(d&15)<<2|e>>6,h=e&63,isNaN(d)?g=h=64:isNaN(e)&&(h=64),a.push([this._keyStr.charAt(f),this._keyStr.charAt(c),this._keyStr.charAt(g),this._keyStr.charAt(h)].join(""));return a.join("")},decode:function(b,a){for(var c=[],d,e,f,g,h, +k=0,b=b.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,e=(e&15)<<4|g>>2,f=(g&3)<<6|h,c.push(String.fromCharCode(d)),64!=g&&c.push(String.fromCharCode(e)),64!=h&&c.push(String.fromCharCode(f));c=c.join("");a&&(c=JXG.Util.Base64._utf8_decode(c));return c},_utf8_encode:function(b){for(var b=b.replace(/\r\n/g,"\n"),a="",c=0;cd?a+=String.fromCharCode(d):(127d?a+=String.fromCharCode(d>>6|192):(a+=String.fromCharCode(d>>12|224),a+=String.fromCharCode(d>>6&63|128)),a+=String.fromCharCode(d&63|128))}return a},_utf8_decode:function(b){for(var a=[],c=0,d=0,e=0,f=0;cd?(a.push(String.fromCharCode(d)),c++):191d?(e=b.charCodeAt(c+1),a.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=b.charCodeAt(c+1),f=b.charCodeAt(c+2),a.push(String.fromCharCode((d&15)<<12| +(e&63)<<6|f&63)),c+=3);return a.join("")},_destrip:function(b,a){var c=[],d,e,f=[];null==a&&(a=76);b.replace(/ /g,"");d=b.length/a;for(e=0;ed?(a.push(String.fromCharCode(d)),c++):191d?(e=b.charCodeAt(c+1),a.push(String.fromCharCode((d&31)<<6|e&63)),c+=2):(e=b.charCodeAt(c+1),f=b.charCodeAt(c+2),a.push(String.fromCharCode((d&15)<<12|(e&63)<<6|f&63)),c+=3);return a.join("")}; +JXG.Util.genUUID=function(){for(var b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),a=Array(36),c=0,d,e=0;36>e;e++)8==e||13==e||18==e||23==e?a[e]="-":14==e?a[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,a[e]=b[19==e?d&3|8:d]);return a.join("")}; +function openpgp_msg_message(){this.text="";this.decrypt=function(b,a){return this.decryptAndVerifySignature(b,a).text};this.decryptAndVerifySignature=function(b,a,c){if(null==b||null==a||""==a)return null;b=a.decrypt(this,b.keymaterial);if(null==b)return null;var d,a=0,e=b.length,f=[];for(util.print_debug_hexstr_dump("openpgp.msg.messge decrypt:\n",b);a!=b.length&&null!=(d=openpgp_packet.read_packet(b,a,e));){if(8==d.tagType)this.text=d.decompress(),b=d.decompress();util.print_debug(d.toString()); +a+=d.headerLength+d.packetLength;38d.signatureType){if(!c||0==c.length)c=openpgp.keyring.getPublicKeysForKeyId(d.issuerKeyId);0==c.length?(util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(d.issuerKeyId)+". Public key not found in keyring."),f[f.length]=!1):d.verify(this.text.replace(/\r\n/g, +"\n").replace(/\n/g,"\r\n"),c[0])&&c[0].obj.validate()?(util.print_info("Found Good Signature from "+c[0].obj.userIds[0].text+" (0x"+util.hexstrdump(c[0].obj.getKeyId()).substring(8)+")"),f[f.length]=!0):(util.print_error("Signature verification failed: Bad Signature from "+c[0].obj.userIds[0].text+" (0x"+util.hexstrdump(c[0].obj.getKeyId()).substring(8)+")"),f[f.length]=!1)}}if(""==this.text)this.text=b;return{text:this.text,validSignatures:f}};this.verifySignature=function(b){var a=!1;if(2==this.type){if(!b|| +0==b.length)if(4==this.signature.version)b=openpgp.keyring.getPublicKeysForKeyId(this.signature.issuerKeyId);else if(3==this.signature.version)b=openpgp.keyring.getPublicKeysForKeyId(this.signature.keyId);else return util.print_error("unknown signature type on message!"),!1;if(0==b.length)util.print_warning("Unable to verify signature of issuer: "+util.hexstrdump(this.signature.issuerKeyId)+". Public key not found in keyring.");else for(var c=0;ce;e++)if(0==d>>e){c=e;break a}this.mpiBitLength=a+c;this.mpiByteLength=b.length;return this};this.toBin=function(){var b=String.fromCharCode(this.mpiBitLength>>8&255),b=b+String.fromCharCode(this.mpiBitLength&255);return b+=this.MPI};this.getByteLength=function(){return this.mpiByteLength}} +function openpgp_type_keyid(){this.read_packet=function(b,a){this.bytes=b.substring(a,a+8);return this};this.toString=function(){return util.hexstrdump(this.bytes)}} +function openpgp_type_s2k(){this.read=function(b,a){var c=a;this.type=b[c++].charCodeAt();switch(this.type){case 0:this.hashAlgorithm=b[c++].charCodeAt();this.s2kLength=1;break;case 1:this.hashAlgorithm=b[c++].charCodeAt();this.saltValue=b.substring(c,c+8);this.s2kLength=9;break;case 3:this.hashAlgorithm=b[c++].charCodeAt();this.saltValue=b.substring(c,c+8);c+=8;this.EXPBIAS=6;c=b[c++].charCodeAt();this.count=16+(c&15)<<(c>>4)+this.EXPBIAS;this.s2kLength=10;break;default:util.print_error("unknown s2k type! "+ +this.type)}return this};this.write=function(b,a,c,d,e){this.type=b;if(3==this.type)this.saltValue=d,this.hashAlgorithm=a,this.count=16+(e&15)<<(e>>4)+6,this.s2kLength=10;return this.produce_key(c)};this.produce_key=function(b,a){if(0==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,b);if(1==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+b);if(3==this.type){var c=[];for(c[0]=this.saltValue+b;c.length*(this.saltValue+b).lengththis.count&&(c=c.substr(0,this.count));return a&&(24==a||32==a)?openpgp_crypto_hashData(this.hashAlgorithm,c)+openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+c):openpgp_crypto_hashData(this.hashAlgorithm,c)}return null}} +function openpgp_keyring(){this.init=function(){var b=JSON.parse(window.localStorage.getItem("privatekeys")),a=JSON.parse(window.localStorage.getItem("publickeys"));if(null==b||0==b.length)b=[];if(null==a||0==a.length)a=[];this.publicKeys=[];this.privateKeys=[];for(var c=0,d=0;d")[0]: +b.trim(),d=d.toLowerCase();if(!util.emailRegEx.test(d))return a;for(b=0;b")[0]:b.trim(),d=d.toLowerCase();if(!util.emailRegEx.test(d))return a;for(b=0;be.length;)e="0"+e;a.push(" "+e);f++;0==f%32&&a.push("\n ")}return a.join("")};this.hexstrdump=function(b){if(null==b)return"";for(var a=[],c=b.length,d=0,e;de.length;)e= +"0"+e;a.push(""+e)}return a.join("")};this.hex2bin=function(b){for(var a="",c=0;ce.length;)e="0"+e;a.push(""+e)}return a.join("")};this.str2bin=function(b){for(var a=[],c=0;c

'+ +b.replace(/\n/g,"
")+"

"))};this.print_debug_hexstr_dump=function(b,a){openpgp.config.debug&&(b+=this.hexstrdump(a),b=openpgp_encoding_html_encode(b),showMessages('

'+b.replace(/\n/g,"
")+"

"))};this.print_error=function(b){b=openpgp_encoding_html_encode(b);showMessages('

ERROR:\t'+ +b.replace(/\n/g,"
")+"

")};this.print_info=function(b){b=openpgp_encoding_html_encode(b);showMessages('

INFO:\t'+b.replace(/\n/g,"
")+"

")};this.print_warning=function(b){b=openpgp_encoding_html_encode(b);showMessages('

WARNING:\t'+ +b.replace(/\n/g,"
")+"

")};this.getLeftNBits=function(b,a){var c=a%8;return 0==c?b.substring(0,a/8):this.shiftRight(b.substring(0,(a-c)/8+1),8-c)};this.shiftRight=function(b,a){var c=util.str2bin(b);if(0!=a%8)for(var d=c.length-1;0<=d;d--)c[d]>>=a%8,0