Crypt-Tea_JS
view release on metacpan or search on metacpan
while (1) {
if (ibl >= nbl) break;
bytes[iby] = 0xFF & (blocks[ibl] >>> 24); iby++;
bytes[iby] = 0xFF & (blocks[ibl] >>> 16); iby++;
bytes[iby] = 0xFF & (blocks[ibl] >>> 8); iby++;
bytes[iby] = 0xFF & blocks[ibl]; iby++;
ibl++;
}
return bytes;
}
function digest_pad (bytearray) {
// add 1 char ('0'..'15') at front to specify no of \x00 pad chars at end
var newarray = new Array(); var ina = 0;
var iba = 0; var nba = bytearray.length;
var npads = 15 - (nba % 16); newarray[ina] = npads; ina++;
while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
var ip = npads; while (ip>0) { newarray[ina] = 0; ina++; ip--; }
return newarray;
}
function pad (bytearray) {
// add 1 char ('0'..'7') at front to specify no of rand pad chars at end
// unshift and push fail on Netscape 4.7 :-(
var newarray = new Array(); var ina = 0;
var iba = 0; var nba = bytearray.length;
var npads = 7 - (nba % 8);
newarray[ina] = (0xF8 & rand_byte()) | (7 & npads); ina++;
while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
var ip = npads; while (ip>0) { newarray[ina] = rand_byte(); ina++; ip--; }
return newarray;
}
function rand_byte() { // used by pad
return Math.floor( 256*Math.random() ); // Random needs js1.1 . Seed ?
// for js1.0 compatibility, could try following ...
if (! rand_byte_already_called) {
var now = new Date(); seed = now.milliseconds;
rand_byte_already_called = true;
}
seed = (1029*seed + 221591) % 1048576; // see Fortran77, Wagener, p177
return Math.floor(seed / 4096);
}
function unpad (bytearray) {
// remove no of pad chars at end specified by 1 char ('0'..'7') at front
// unshift and push fail on Netscape 4.7 :-(
var iba = 0;
var newarray = new Array(); var ina = 0;
var npads = 0x7 & bytearray[iba]; iba++; var nba = bytearray.length - npads;
while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
return newarray;
}
// --- TEA stuff, translated from the Perl Tea_JS.pm see www.pjb.com.au/comp ---
// In JavaScript we express an 8-byte block as an array of 2 32-bit ints
function asciidigest (str) {
return binary2ascii( binarydigest(str) );
}
function binarydigest (str, keystr) { // returns 22-char ascii signature
var key = new Array(); // key = binarydigest(keystr);
key[0]=0x61626364; key[1]=0x62636465; key[2]=0x63646566; key[3]=0x64656667;
// Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
var c0 = new Array(); c0[0] = 0x61626364; c0[1] = 0x62636465;
var c1 = new Array(); c1 = c0;
var v0 = new Array(); var v1 = new Array(); var swap;
var blocks = new Array(); blocks = bytes2blocks(digest_pad(str2bytes(str)));
var ibl = 0; var nbl = blocks.length;
while (1) {
if (ibl >= nbl) break;
v0[0] = blocks[ibl]; ibl++; v0[1] = blocks[ibl]; ibl++;
v1[0] = blocks[ibl]; ibl++; v1[1] = blocks[ibl]; ibl++;
// cipher them XOR'd with previous stage ...
c0 = tea_code( xor_blocks(v0,c0), key );
c1 = tea_code( xor_blocks(v1,c1), key );
// mix up the two cipher blocks with a 32-bit left rotation ...
swap=c0[0]; c0[0]=c0[1]; c0[1]=c1[0]; c1[0]=c1[1]; c1[1]=swap;
}
var concat = new Array();
concat[0]=c0[0]; concat[1]=c0[1]; concat[2]=c1[0]; concat[3]=c1[1];
return concat;
}
function encrypt (str,keystr) { // encodes with CBC (Cipher Block Chaining)
if (! keystr) { alert("encrypt: no key"); return false; }
var key = new Array(); key = binarydigest(keystr);
if (! str) return "";
var blocks = new Array(); blocks = bytes2blocks(pad(str2bytes(str)));
var ibl = 0; var nbl = blocks.length;
// Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
var c = new Array(); c[0] = 0x61626364; c[1] = 0x62636465;
var v = new Array(); var cblocks = new Array(); var icb = 0;
while (1) {
if (ibl >= nbl) break;
v[0] = blocks[ibl]; ibl++; v[1] = blocks[ibl]; ibl++;
c = tea_code( xor_blocks(v,c), key );
cblocks[icb] = c[0]; icb++; cblocks[icb] = c[1]; icb++;
}
return binary2ascii(cblocks);
}
function decrypt (ascii, keystr) { // decodes with CBC
if (! keystr) { alert("decrypt: no key"); return false; }
var key = new Array(); key = binarydigest(keystr);
if (! ascii) return "";
var cblocks = new Array(); cblocks = ascii2binary(ascii);
var icbl = 0; var ncbl = cblocks.length;
// Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
var lastc = new Array(); lastc[0] = 0x61626364; lastc[1] = 0x62636465;
var v = new Array(); var c = new Array();
var blocks = new Array(); var ibl = 0;
while (1) {
if (icbl >= ncbl) break;
c[0] = cblocks[icbl]; icbl++; c[1] = cblocks[icbl]; icbl++;
v = xor_blocks( lastc, tea_decode(c,key) );
blocks[ibl] = v[0]; ibl++; blocks[ibl] = v[1]; ibl++;
lastc[0] = c[0]; lastc[1] = c[1];
}
return bytes2str(unpad(blocks2bytes(blocks)));
}
function xor_blocks(blk1, blk2) { // xor of two 8-byte blocks
var blk = new Array();
blk[0] = blk1[0]^blk2[0]; blk[1] = blk1[1]^blk2[1];
return blk;
}
function tea_code (v, k) {
// NewTEA. 2-int (64-bit) cyphertext block in v. 4-int (128-bit) key in k.
var v0 = v[0]; var v1 = v[1];
var sum = 0; var n = 32;
while (n-- > 0) {
v0 += (((v1<<4)^(v1>>>5))+v1) ^ (sum+k[sum&3]) ; v0 = v0|0 ;
sum -= 1640531527; // TEA magic number 0x9e3779b9
sum = sum|0; // force it back to 32-bit int
v1 += (((v0<<4)^(v0>>>5))+v0) ^ (sum+k[(sum>>>11)&3]); v1 = v1|0 ;
}
var w = new Array(); w[0] = v0; w[1] = v1; return w;
}
function tea_decode (v, k) {
// NewTEA. 2-int (64-bit) cyphertext block in v. 4-int (128-bit) key in k.
var v0 = v[0]; var v1 = v[1];
var sum = 0; var n = 32;
sum = -957401312 ; // TEA magic number 0x9e3779b9<<5
while (n-- > 0) {
v1 -= (((v0<<4)^(v0>>>5))+v0) ^ (sum+k[(sum>>>11)&3]); v1 = v1|0 ;
sum += 1640531527; // TEA magic number 0x9e3779b9 ;
sum = sum|0; // force it back to 32-bit int
v0 -= (((v1<<4)^(v1>>>5))+v1) ^ (sum+k[sum&3]); v0 = v0|0 ;
}
var w = new Array(); w[0] = v0; w[1] = v1; return w;
}
// ------------- assocarys used by the conversion routines -----------
c2b = new Object();
c2b["\x00"]=0; c2b["\x01"]=1; c2b["\x02"]=2; c2b["\x03"]=3;
c2b["\x04"]=4; c2b["\x05"]=5; c2b["\x06"]=6; c2b["\x07"]=7;
c2b["\x08"]=8; c2b["\x09"]=9; c2b["\x0A"]=10; c2b["\x0B"]=11;
c2b["\x0C"]=12; c2b["\x0D"]=13; c2b["\x0E"]=14; c2b["\x0F"]=15;
c2b["\x10"]=16; c2b["\x11"]=17; c2b["\x12"]=18; c2b["\x13"]=19;
c2b["\x14"]=20; c2b["\x15"]=21; c2b["\x16"]=22; c2b["\x17"]=23;
c2b["\x18"]=24; c2b["\x19"]=25; c2b["\x1A"]=26; c2b["\x1B"]=27;
c2b["\x1C"]=28; c2b["\x1D"]=29; c2b["\x1E"]=30; c2b["\x1F"]=31;
c2b["\x20"]=32; c2b["\x21"]=33; c2b["\x22"]=34; c2b["\x23"]=35;
c2b["\x24"]=36; c2b["\x25"]=37; c2b["\x26"]=38; c2b["\x27"]=39;
c2b["\x28"]=40; c2b["\x29"]=41; c2b["\x2A"]=42; c2b["\x2B"]=43;
c2b["\x2C"]=44; c2b["\x2D"]=45; c2b["\x2E"]=46; c2b["\x2F"]=47;
c2b["\x30"]=48; c2b["\x31"]=49; c2b["\x32"]=50; c2b["\x33"]=51;
c2b["\x34"]=52; c2b["\x35"]=53; c2b["\x36"]=54; c2b["\x37"]=55;
c2b["\x38"]=56; c2b["\x39"]=57; c2b["\x3A"]=58; c2b["\x3B"]=59;
( run in 0.776 second using v1.01-cache-2.11-cpan-e1769b4cff6 )