Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / Crypt / Tea.pm
CommitLineData
86530b38
AT
1# Tea.pm
2#########################################################################
3# This Perl module is Copyright (c) 2000, Peter J Billam #
4# c/o P J B Computing, www.pjb.com.au #
5# #
6# This module is free software; you can redistribute it and/or #
7# modify it under the same terms as Perl itself. #
8#########################################################################
9#
10# implements TEA, the Tiny Encryption Algorithm, in Perl and Javascript.
11# http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
12#
13# Usage:
14# use Tea;
15# $key = 'PUFgob$*LKDF D)(F IDD&P?/';
16# $ascii_ciphertext = &encrypt ($plaintext, $key);
17# ...
18# $plaintext_again = &decrypt ($ascii_ciphertext, $key);
19# ...
20# $signature = &asciidigest ($text);
21#
22# The $key is a sufficiently longish string; at least 17 random 8-bit bytes
23#
24# Written by Peter J Billam, http://www.pjb.com.au
25
26package Crypt::Tea;
27$VERSION = '1.43';
28
29# Don't like depending on externals; this is strong encrytion ... but ...
30use Exporter; @ISA = qw(Exporter);
31@EXPORT=qw(asciidigest encrypt decrypt
32 tea_in_javascript str2ascii ascii2str encrypt_and_write);
33
34# begin config
35my %a2b = (
36 A=>000, B=>001, C=>002, D=>003, E=>004, F=>005, G=>006, H=>007,
37 I=>010, J=>011, K=>012, L=>013, M=>014, N=>015, O=>016, P=>017,
38 Q=>020, R=>021, S=>022, T=>023, U=>024, V=>025, W=>026, X=>027,
39 Y=>030, Z=>031, a=>032, b=>033, c=>034, d=>035, e=>036, f=>037,
40 g=>040, h=>041, i=>042, j=>043, k=>044, l=>045, m=>046, n=>047,
41 o=>050, p=>051, q=>052, r=>053, s=>054, t=>055, u=>056, v=>057,
42 w=>060, x=>061, y=>062, z=>063, '0'=>064, '1'=>065, '2'=>066, '3'=>067,
43 '4'=>070,'5'=>071,'6'=>072,'7'=>073,'8'=>074,'9'=>075,'+'=>076,'_'=>077,
44);
45my %b2a = reverse %a2b;
46# end config
47
48# ------------------ infrastructure ...
49
50sub tea_in_javascript {
51 my @js; while (<DATA>) { last if /^EOT$/; push @js, $_; } join '', @js;
52}
53sub encrypt_and_write { my ($str, $key) = @_;
54 return unless $str; return unless $key;
55 print
56 "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\nparent.decrypt_and_write('";
57 print &encrypt($str,$key);
58 print "');\n// -->\n</SCRIPT>\n";
59}
60sub binary2ascii {
61 return &str2ascii(&binary2str(@_));
62}
63sub ascii2binary {
64 return &str2binary(&ascii2str($_[$[]));
65}
66sub str2binary { my @str = split //, $_[$[];
67 my @intarray = (); my $ii = $[;
68 while (1) {
69 last unless @str; $intarray[$ii] = (0xFF & ord shift @str)<<24;
70 last unless @str; $intarray[$ii] |= (0xFF & ord shift @str)<<16;
71 last unless @str; $intarray[$ii] |= (0xFF & ord shift @str)<<8;
72 last unless @str; $intarray[$ii] |= 0xFF & ord shift @str;
73 $ii++;
74 }
75 return @intarray;
76}
77sub binary2str {
78 my @str = ();
79 foreach $i (@_) {
80 push @str, chr (0xFF & ($i>>24)), chr (0xFF & ($i>>16)),
81 chr (0xFF & ($i>>8)), chr (0xFF & $i);
82 }
83 return join '', @str;
84}
85sub ascii2str { my $a = $_[$[]; # converts pseudo-base64 to string of bytes
86 $a =~ tr#A-Za-z0-9+_##cd;
87 my $ia = $[-1; my $la = length $a; # BUG not length, final!
88 my $ib = $[; my @b = ();
89 my $carry;
90 while (1) { # reads 4 ascii chars and produces 3 bytes
91 $ia++; last if ($ia>=$la);
92 $b[$ib] = $a2b{substr $a, $ia+$[, 1}<<2;
93 $ia++; last if ($ia>=$la);
94 $carry=$a2b{substr $a, $ia+$[, 1}; $b[$ib] |= ($carry>>4); $ib++;
95 # if low 4 bits of $carry are 0 and its the last char, then break
96 $carry = 0xF & $carry; last if ($carry == 0 && $ia == ($la-1));
97 $b[$ib] = $carry<<4;
98 $ia++; last if ($ia>=$la);
99 $carry=$a2b{substr $a, $ia+$[, 1}; $b[$ib] |= ($carry>>2); $ib++;
100 # if low 2 bits of $carry are 0 and its the last char, then break
101 $carry = 03 & $carry; last if ($carry == 0 && $ia == ($la-1));
102 $b[$ib] = $carry<<6;
103 $ia++; last if ($ia>=$la);
104 $b[$ib] |= $a2b{substr $a, $ia+$[, 1}; $ib++;
105 }
106 return pack 'c*', @b;
107}
108sub str2ascii { my $b = $_[$[]; # converts string of bytes to pseudo-base64
109 my $ib = $[; my $lb = length $b; my @s = ();
110 my $b1; my $b2; my $b3;
111 my $carry;
112 while (1) { # reads 3 bytes and produces 4 ascii chars
113 if ($ib >= $lb) { last; };
114 $b1 = ord substr $b, $ib+$[, 1; $ib++;
115 push @s, $b2a{$b1>>2}; $carry = 03 & $b1;
116 if ($ib >= $lb) { push @s, $b2a{$carry<<4}; last; }
117 $b2 = ord substr $b, $ib+$[, 1; $ib++;
118 push @s, $b2a{($b2>>4) | ($carry<<4)}; $carry = 0xF & $b2;
119 if ($ib >= $lb) { push @s, $b2a{$carry<<2}; last; }
120 $b3 = ord substr $b, $ib+$[, 1; $ib++;
121 push @s, $b2a{($b3>>6) | ($carry<<2)}, $b2a{077 & $b3};
122 if (!$ENV{REMOTE_ADDR} && (($ib % 36) == 0)) { push @s, "\n"; }
123 }
124 return join ('', @s);
125}
126sub asciidigest { # returns 22-char ascii signature
127 return &binary2ascii(&binarydigest($_[$[]));
128}
129sub binarydigest { my $str = $_[$[]; # returns 4 32-bit-int binary signature
130 # warning: mode of use invented by Peter Billam 1998, needs checking !
131 return '' unless $str;
132 # add 1 char ('0'..'15') at front to specify no of pad chars at end ...
133 my $npads = 15 - ((length $str) % 16);
134 $str = chr($npads) . $str;
135 if ($npads) { $str .= "\0" x $npads; }
136 my @str = &str2binary($str);
137 my @key = (0x61626364, 0x62636465, 0x63646566, 0x64656667);
138
139 my ($cswap, $v0, $v1, $v2, $v3);
140 my $c0 = 0x61626364; my $c1 = 0x62636465; # CBC Initial Value. Retain !
141 my $c2 = 0x61626364; my $c3 = 0x62636465; # likewise (abcdbcde).
142 while (@str) {
143 # shift 2 blocks off front of str ...
144 $v0 = shift @str; $v1 = shift @str; $v2 = shift @str; $v3 = shift @str;
145 # cipher them XOR'd with previous stage ...
146 ($c0,$c1) = &tea_code ($v0^$c0, $v1^$c1, @key);
147 ($c2,$c3) = &tea_code ($v2^$c2, $v3^$c3, @key);
148 # mix up the two cipher blocks with a 4-byte left rotation ...
149 $cswap = $c0; $c0=$c1; $c1=$c2; $c2=$c3; $c3=$cswap;
150 }
151 return ($c0,$c1,$c2,$c3);
152}
153sub encrypt { my ($str,$key)=@_; # encodes with CBC (Cipher Block Chaining)
154 use integer;
155 return '' unless $str; return '' unless $key;
156 @key = &binarydigest($key);
157
158 # add 1 char ('0'..'7') at front to specify no of pad chars at end ...
159 my $npads = 7 - ((length $str) % 8);
160 $str = chr($npads|(0xF8 & &rand_byte)) . $str;
161 if ($npads) {
162 my $padding = pack 'CCCCCCC', &rand_byte, &rand_byte,
163 &rand_byte, &rand_byte, &rand_byte, &rand_byte, &rand_byte;
164 $str = $str . substr($padding,$[,$npads);
165 }
166 my @pblocks = &str2binary($str);
167 my $v0; my $v1;
168 my $c0 = 0x61626364; my $c1 = 0x62636465; # CBC Initial Value. Retain !
169 my @cblocks;
170 while (1) {
171 last unless @pblocks; $v0 = shift @pblocks; $v1 = shift @pblocks;
172 ($c0,$c1) = &tea_code ($v0^$c0, $v1^$c1, @key);
173 push @cblocks, $c0, $c1;
174 }
175 my $btmp = &binary2str(@cblocks);
176 return &str2ascii( &binary2str(@cblocks) );
177}
178sub decrypt { my ($acstr, $key) = @_; # decodes with CBC
179 use integer;
180 return '' unless $acstr; return '' unless $key;
181 @key = &binarydigest($key);
182 my $v0; my $v1; my $c0; my $c1; my @pblocks = (); my $de0; my $de1;
183 my $lastc0 = 0x61626364; my $lastc1 = 0x62636465; # CBC Init Val. Retain!
184 my @cblocks = &str2binary( &ascii2str($acstr) );
185 while (1) {
186 last unless @cblocks; $c0 = shift @cblocks; $c1 = shift @cblocks;
187 ($de0, $de1) = &tea_decode ($c0,$c1, @key);
188 $v0 = $lastc0 ^ $de0; $v1 = $lastc1 ^ $de1;
189 push @pblocks, $v0, $v1;
190 $lastc0 = $c0; $lastc1 = $c1;
191 }
192 my $str = &binary2str( @pblocks );
193 # remove no of pad chars at end specified by 1 char ('0'..'7') at front
194 my $npads = 0x7 & ord $str; substr ($str, $[, 1) = '';
195 if ($npads) { substr ($str, 0 - $npads) = ''; }
196 return $str;
197}
198sub triple_encrypt { my ($plaintext, $long_key) = @_; # not yet ...
199}
200sub triple_decrypt { my ($cyphertext, $long_key) = @_; # not yet ...
201}
202sub tea_code { my ($v0,$v1, $k0,$k1,$k2,$k3) = @_;
203 # TEA. 64-bit cleartext block in $v0,$v1. 128-bit key in $k0..$k3.
204 # &prn("tea_code: v0=$v0 v1=$v1");
205 use integer;
206 my $sum = 0; my $n = 32;
207 while ($n-- > 0) {
208 $sum += 0x9e3779b9; # TEA magic number delta
209 $v0 += (($v1<<4)+$k0) ^ ($v1+$sum) ^ ((0x07FFFFFF & ($v1>>5))+$k1) ;
210 $v1 += (($v0<<4)+$k2) ^ ($v0+$sum) ^ ((0x07FFFFFF & ($v0>>5))+$k3) ;
211 }
212 return ($v0, $v1);
213}
214sub tea_decode { my ($v0,$v1, $k0,$k1,$k2,$k3) = @_;
215 # TEA. 64-bit cyphertext block in $v0,$v1. 128-bit key in $k0..$k3.
216 use integer;
217 my $sum = 0; my $n = 32;
218 $sum = 0x9e3779b9 << 5 ; # TEA magic number delta
219 while ($n-- > 0) {
220 $v1 -= (($v0<<4)+$k2) ^ ($v0+$sum) ^ ((0x07FFFFFF & ($v0>>5))+$k3) ;
221 $v0 -= (($v1<<4)+$k0) ^ ($v1+$sum) ^ ((0x07FFFFFF & ($v1>>5))+$k1) ;
222 $sum -= 0x9e3779b9 ;
223 }
224 return ($v0, $v1);
225}
226sub rand_byte {
227 if (! $rand_byte_already_called) {
228 # Jengwei Pan to keep the same seed
229 #srand(time() ^ ($$+($$<<15))); # could do better, but its only padding
230 srand(1121);
231 $rand_byte_already_called = 1;
232 }
233 int(rand 256);
234}
2351;
236
237__DATA__
238
239<SCRIPT LANGUAGE="JavaScript">
240<!--
241// This JavaScript is Copyright (c) 2000, Peter J Billam
242// c/o P J B Computing, www.pjb.com.au
243// It was generated by the Crypt::Tea.pm Perl module and is free software;
244// you can redistribute and modify it under the same terms as Perl itself.
245
246// -- conversion routines between string, bytes, ascii encoding, & blocks --
247function binary2ascii (s) {
248 return bytes2ascii( blocks2bytes(s) );
249}
250function binary2str (s) {
251 return bytes2str( blocks2bytes(s) );
252}
253function ascii2binary (s) {
254 return bytes2blocks( ascii2bytes(s) );
255}
256function str2binary (s) {
257 return bytes2blocks( str2bytes(s) );
258}
259function str2bytes(s) { // converts string to array of bytes
260 var is = 0; var ls = s.length; var b = new Array();
261 while (1) {
262 if (is >= ls) break;
263 if (c2b[s.charAt(is)] == null) { b[is] = 0xF7;
264 alert ('is = '+is + '\nchar = '+s.charAt(is) + '\nls = '+ls);
265 } else { b[is] = c2b[s.charAt(is)];
266 }
267 is++;
268 }
269 return b;
270}
271function bytes2str(b) { // converts array of bytes to string
272 var ib = 0; var lb = b.length; var s = '';
273 while (1) {
274 if (ib >= lb) break;
275 s += b2c[0xFF&b[ib]]; // if its like perl, could be faster with join
276 ib++;
277 }
278 return s;
279}
280function ascii2bytes(a) { // converts pseudo-base64 to array of bytes
281 var ia = -1; var la = a.length;
282 var ib = 0; var b = new Array();
283 var carry;
284 while (1) { // reads 4 chars and produces 3 bytes
285 while (1) { ia++; if (ia>=la) return b; if (a2b[a.charAt(ia)]!=null) break; }
286 b[ib] = a2b[a.charAt(ia)]<<2;
287 while (1) { ia++; if (ia>=la) return b; if (a2b[a.charAt(ia)]!=null) break; }
288 carry=a2b[a.charAt(ia)]; b[ib] |= carry>>>4; ib++;
289 // if low 4 bits of carry are 0 and its the last char, then break
290 carry = 0xF & carry;
291 if (carry == 0 && ia == (la-1)) return b;
292 b[ib] = carry<<4;
293 while (1) { ia++; if (ia>=la) return b; if (a2b[a.charAt(ia)]!=null) break; }
294 carry=a2b[a.charAt(ia)]; b[ib] |= carry>>>2; ib++;
295 // if low 2 bits of carry are 0 and its the last char, then break
296 carry = 03 & carry;
297 if (carry == 0 && ia == (la-1)) return b;
298 b[ib] = carry<<6;
299 while (1) { ia++; if (ia>=la) return b; if (a2b[a.charAt(ia)]!=null) break; }
300 b[ib] |= a2b[a.charAt(ia)]; ib++;
301 }
302 return b;
303}
304function bytes2ascii(b) { // converts array of bytes to pseudo-base64 ascii
305 var ib = 0; var lb = b.length; var s = '';
306 var b1; var b2; var b3;
307 var carry;
308 while (1) { // reads 3 bytes and produces 4 chars
309 if (ib >= lb) break; b1 = 0xFF & b[ib];
310 s += b2a[077 & (b1>>>2)];
311 carry = 03 & b1;
312 ib++; if (ib >= lb) { s += b2a[carry<<4]; break; } b2 = 0xFF & b[ib];
313 s += b2a[(0xF0 & (carry<<4)) | (b2>>>4)];
314 carry = 0xF & b2;
315 ib++; if (ib >= lb) { s += b2a[carry<<2]; break; } b3 = 0xFF & b[ib];
316 s += b2a[(074 & (carry<<2)) | (b3>>>6)] + b2a[077 & b3];
317 ib++;
318 if (ib % 36 == 0) s += "\n";
319 }
320 return s;
321}
322function bytes2blocks(bytes) {
323 var blocks = new Array(); var ibl = 0;
324 var iby = 0; var nby = bytes.length;
325 while (1) {
326 blocks[ibl] = (0xFF & bytes[iby])<<24; iby++; if (iby >= nby) break;
327 blocks[ibl] |= (0xFF & bytes[iby])<<16; iby++; if (iby >= nby) break;
328 blocks[ibl] |= (0xFF & bytes[iby])<<8; iby++; if (iby >= nby) break;
329 blocks[ibl] |= 0xFF & bytes[iby]; iby++; if (iby >= nby) break;
330 ibl++;
331 }
332 return blocks;
333}
334function blocks2bytes(blocks) {
335 var bytes = new Array(); var iby = 0;
336 var ibl = 0; var nbl = blocks.length;
337 while (1) {
338 if (ibl >= nbl) break;
339 bytes[iby] = 0xFF & (blocks[ibl] >>> 24); iby++;
340 bytes[iby] = 0xFF & (blocks[ibl] >>> 16); iby++;
341 bytes[iby] = 0xFF & (blocks[ibl] >>> 8); iby++;
342 bytes[iby] = 0xFF & blocks[ibl]; iby++;
343 ibl++;
344 }
345 return bytes;
346}
347function digest_pad (bytearray) {
348 // add 1 char ('0'..'15') at front to specify no of \0 pad chars at end
349 var newarray = new Array(); var ina = 0;
350 var iba = 0; var nba = bytearray.length;
351 var npads = 15 - (nba % 16); newarray[ina] = npads; ina++;
352 while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
353 var ip = npads; while (ip>0) { newarray[ina] = 0; ina++; ip--; }
354 return newarray;
355}
356function pad (bytearray) {
357 // add 1 char ('0'..'7') at front to specify no of rand pad chars at end
358 // unshift and push fail on Netscape 4.7 :-(
359 var newarray = new Array(); var ina = 0;
360 var iba = 0; var nba = bytearray.length;
361 var npads = 7 - (nba % 8);
362 newarray[ina] = (0xF8 & rand_byte()) | (07 & npads); ina++;
363 while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
364 var ip = npads; while (ip>0) { newarray[ina] = rand_byte(); ina++; ip--; }
365 return newarray;
366}
367function rand_byte() { // used by pad
368 return Math.floor( 256*Math.random() ); // Random needs js1.1 . Seed ?
369 // for js1.0 compatibility, could try following ...
370 if (! rand_byte_already_called) {
371 var now = new Date(); seed = now.milliseconds;
372 rand_byte_already_called = true;
373 }
374 seed = (1029*seed + 221591) % 1048576; // see Fortran77, Wagener, p177
375 return Math.floor(seed / 4096);
376}
377function unpad (bytearray) {
378 // remove no of pad chars at end specified by 1 char ('0'..'7') at front
379 // unshift and push fail on Netscape 4.7 :-(
380 var iba = 0;
381 var newarray = new Array(); var ina = 0;
382 var npads = 0x7 & bytearray[iba]; iba++; var nba = bytearray.length - npads;
383 while (iba < nba) { newarray[ina] = bytearray[iba]; ina++; iba++; }
384 return newarray;
385}
386
387// --- TEA stuff, translated from the Perl Tea.pm see www.pjb.com.au/comp ---
388
389// In JavaScript we express an 8-byte block as an array of 2 32-bit ints
390function asciidigest (str) {
391 return binary2ascii( binarydigest(str) );
392}
393function binarydigest (str, keystr) { // returns 22-char ascii signature
394 var key = new Array(); // key = binarydigest(keystr);
395 key[0]=0x61626364; key[1]=0x62636465; key[2]=0x63646566; key[3]=0x64656667;
396
397 // Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
398 var c0 = new Array(); c0[0] = 0x61626364; c0[1] = 0x62636465;
399 var c1 = new Array(); c1 = c0;
400
401 var v0 = new Array(); var v1 = new Array(); var swap;
402 var blocks = new Array(); blocks = bytes2blocks(digest_pad(str2bytes(str)));
403 var ibl = 0; var nbl = blocks.length;
404 while (1) {
405 if (ibl >= nbl) break;
406 v0[0] = blocks[ibl]; ibl++; v0[1] = blocks[ibl]; ibl++;
407 v1[0] = blocks[ibl]; ibl++; v1[1] = blocks[ibl]; ibl++;
408 // cipher them XOR'd with previous stage ...
409 c0 = tea_code( xor_blocks(v0,c0), key );
410 c1 = tea_code( xor_blocks(v1,c1), key );
411 // mix up the two cipher blocks with a 32-bit left rotation ...
412 swap=c0[0]; c0[0]=c0[1]; c0[1]=c1[0]; c1[0]=c1[1]; c1[1]=swap;
413 }
414 var concat = new Array();
415 concat[0]=c0[0]; concat[1]=c0[1]; concat[2]=c1[0]; concat[3]=c1[1];
416 return concat;
417}
418function encrypt (str,keystr) { // encodes with CBC (Cipher Block Chaining)
419 if (! keystr) { alert("encrypt: no key"); return false; }
420 var key = new Array(); key = binarydigest(keystr);
421 if (! str) return "";
422 var blocks = new Array(); blocks = bytes2blocks(pad(str2bytes(str)));
423 var ibl = 0; var nbl = blocks.length;
424 // Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
425 var c = new Array(); c[0] = 0x61626364; c[1] = 0x62636465;
426 var v = new Array(); var cblocks = new Array(); var icb = 0;
427 while (1) {
428 if (ibl >= nbl) break;
429 v[0] = blocks[ibl]; ibl++; v[1] = blocks[ibl]; ibl++;
430 c = tea_code( xor_blocks(v,c), key );
431 cblocks[icb] = c[0]; icb++; cblocks[icb] = c[1]; icb++;
432 }
433 return binary2ascii(cblocks);
434}
435function decrypt (ascii, keystr) { // decodes with CBC
436 if (! keystr) { alert("decrypt: no key"); return false; }
437 var key = new Array(); key = binarydigest(keystr);
438 if (! ascii) return "";
439 var cblocks = new Array(); cblocks = ascii2binary(ascii);
440 var icbl = 0; var ncbl = cblocks.length;
441 // Initial Value for CBC mode = "abcdbcde". Retain for interoperability.
442 var lastc = new Array(); lastc[0] = 0x61626364; lastc[1] = 0x62636465;
443 var v = new Array(); var c = new Array();
444 var blocks = new Array(); var ibl = 0;
445 while (1) {
446 if (icbl >= ncbl) break;
447 c[0] = cblocks[icbl]; icbl++; c[1] = cblocks[icbl]; icbl++;
448 v = xor_blocks( lastc, tea_decode(c,key) );
449 blocks[ibl] = v[0]; ibl++; blocks[ibl] = v[1]; ibl++;
450 lastc[0] = c[0]; lastc[1] = c[1];
451 }
452 return bytes2str(unpad(blocks2bytes(blocks)));
453}
454function xor_blocks(blk1, blk2) { // xor of two 8-byte blocks
455 var blk = new Array();
456 blk[0] = blk1[0]^blk2[0]; blk[1] = blk1[1]^blk2[1];
457 return blk;
458}
459function tea_code (v, k) {
460 // TEA. 2-int (64-bit) cyphertext block in v. 4-int (128-bit) key in k.
461 var v0 = v[0]; var v1 = v[1];
462 var k0 = k[0]; var k1 = k[1]; var k2 = k[2]; var k3 = k[3];
463 var sum = 0; var n = 32;
464 while (n-- > 0) {
465 sum += 0x9e3779b9; // TEA magic number
466 v0 += ((v1<<4)+k0) ^ (v1+sum) ^ ((v1>>>5)+k1) ;
467 v1 += ((v0<<4)+k2) ^ (v0+sum) ^ ((v0>>>5)+k3) ;
468 }
469 var w = new Array(); w[0] = v0; w[1] = v1; return w;
470}
471function tea_decode (v, k) {
472 // TEA. 2-int (64-bit) cyphertext block in v. 4-int (128-bit) key in k.
473 var v0 = v[0]; var v1 = v[1];
474 var k0 = k[0]; var k1 = k[1]; var k2 = k[2]; var k3 = k[3];
475 var sum = 0; var n = 32;
476 sum = 0x9e3779b9 << 5 ; // TEA magic number
477 while (n-- > 0) {
478 v1 -= ((v0<<4)+k2) ^ (v0+sum) ^ ((v0>>>5)+k3) ;
479 v0 -= ((v1<<4)+k0) ^ (v1+sum) ^ ((v1>>>5)+k1) ;
480 sum -= 0x9e3779b9 ;
481 }
482 var w = new Array(); w[0] = v0; w[1] = v1; return w;
483}
484
485// ------------- assocarys used by the conversion routines -----------
486c2b = new Object();
487c2b["\000"]=0000; c2b["\001"]=0001; c2b["\002"]=0002; c2b["\003"]=0003;
488c2b["\004"]=0004; c2b["\005"]=0005; c2b["\006"]=0006; c2b["\007"]=0007;
489c2b["\010"]=0010; c2b["\011"]=0011; c2b["\012"]=0012; c2b["\013"]=0013;
490c2b["\014"]=0014; c2b["\015"]=0015; c2b["\016"]=0016; c2b["\017"]=0017;
491c2b["\020"]=0020; c2b["\021"]=0021; c2b["\022"]=0022; c2b["\023"]=0023;
492c2b["\024"]=0024; c2b["\025"]=0025; c2b["\026"]=0026; c2b["\027"]=0027;
493c2b["\030"]=0030; c2b["\031"]=0031; c2b["\032"]=0032; c2b["\033"]=0033;
494c2b["\034"]=0034; c2b["\035"]=0035; c2b["\036"]=0036; c2b["\037"]=0037;
495c2b["\040"]=0040; c2b["\041"]=0041; c2b["\042"]=0042; c2b["\043"]=0043;
496c2b["\044"]=0044; c2b["\045"]=0045; c2b["\046"]=0046; c2b["\047"]=0047;
497c2b["\050"]=0050; c2b["\051"]=0051; c2b["\052"]=0052; c2b["\053"]=0053;
498c2b["\054"]=0054; c2b["\055"]=0055; c2b["\056"]=0056; c2b["\057"]=0057;
499c2b["\060"]=0060; c2b["\061"]=0061; c2b["\062"]=0062; c2b["\063"]=0063;
500c2b["\064"]=0064; c2b["\065"]=0065; c2b["\066"]=0066; c2b["\067"]=0067;
501c2b["\070"]=0070; c2b["\071"]=0071; c2b["\072"]=0072; c2b["\073"]=0073;
502c2b["\074"]=0074; c2b["\075"]=0075; c2b["\076"]=0076; c2b["\077"]=0077;
503c2b["\100"]=0100; c2b["\101"]=0101; c2b["\102"]=0102; c2b["\103"]=0103;
504c2b["\104"]=0104; c2b["\105"]=0105; c2b["\106"]=0106; c2b["\107"]=0107;
505c2b["\110"]=0110; c2b["\111"]=0111; c2b["\112"]=0112; c2b["\113"]=0113;
506c2b["\114"]=0114; c2b["\115"]=0115; c2b["\116"]=0116; c2b["\117"]=0117;
507c2b["\120"]=0120; c2b["\121"]=0121; c2b["\122"]=0122; c2b["\123"]=0123;
508c2b["\124"]=0124; c2b["\125"]=0125; c2b["\126"]=0126; c2b["\127"]=0127;
509c2b["\130"]=0130; c2b["\131"]=0131; c2b["\132"]=0132; c2b["\133"]=0133;
510c2b["\134"]=0134; c2b["\135"]=0135; c2b["\136"]=0136; c2b["\137"]=0137;
511c2b["\140"]=0140; c2b["\141"]=0141; c2b["\142"]=0142; c2b["\143"]=0143;
512c2b["\144"]=0144; c2b["\145"]=0145; c2b["\146"]=0146; c2b["\147"]=0147;
513c2b["\150"]=0150; c2b["\151"]=0151; c2b["\152"]=0152; c2b["\153"]=0153;
514c2b["\154"]=0154; c2b["\155"]=0155; c2b["\156"]=0156; c2b["\157"]=0157;
515c2b["\160"]=0160; c2b["\161"]=0161; c2b["\162"]=0162; c2b["\163"]=0163;
516c2b["\164"]=0164; c2b["\165"]=0165; c2b["\166"]=0166; c2b["\167"]=0167;
517c2b["\170"]=0170; c2b["\171"]=0171; c2b["\172"]=0172; c2b["\173"]=0173;
518c2b["\174"]=0174; c2b["\175"]=0175; c2b["\176"]=0176; c2b["\177"]=0177;
519c2b["\200"]=0200; c2b["\201"]=0201; c2b["\202"]=0202; c2b["\203"]=0203;
520c2b["\204"]=0204; c2b["\205"]=0205; c2b["\206"]=0206; c2b["\207"]=0207;
521c2b["\210"]=0210; c2b["\211"]=0211; c2b["\212"]=0212; c2b["\213"]=0213;
522c2b["\214"]=0214; c2b["\215"]=0215; c2b["\216"]=0216; c2b["\217"]=0217;
523c2b["\220"]=0220; c2b["\221"]=0221; c2b["\222"]=0222; c2b["\223"]=0223;
524c2b["\224"]=0224; c2b["\225"]=0225; c2b["\226"]=0226; c2b["\227"]=0227;
525c2b["\230"]=0230; c2b["\231"]=0231; c2b["\232"]=0232; c2b["\233"]=0233;
526c2b["\234"]=0234; c2b["\235"]=0235; c2b["\236"]=0236; c2b["\237"]=0237;
527c2b["\240"]=0240; c2b["\241"]=0241; c2b["\242"]=0242; c2b["\243"]=0243;
528c2b["\244"]=0244; c2b["\245"]=0245; c2b["\246"]=0246; c2b["\247"]=0247;
529c2b["\250"]=0250; c2b["\251"]=0251; c2b["\252"]=0252; c2b["\253"]=0253;
530c2b["\254"]=0254; c2b["\255"]=0255; c2b["\256"]=0256; c2b["\257"]=0257;
531c2b["\260"]=0260; c2b["\261"]=0261; c2b["\262"]=0262; c2b["\263"]=0263;
532c2b["\264"]=0264; c2b["\265"]=0265; c2b["\266"]=0266; c2b["\267"]=0267;
533c2b["\270"]=0270; c2b["\271"]=0271; c2b["\272"]=0272; c2b["\273"]=0273;
534c2b["\274"]=0274; c2b["\275"]=0275; c2b["\276"]=0276; c2b["\277"]=0277;
535c2b["\300"]=0300; c2b["\301"]=0301; c2b["\302"]=0302; c2b["\303"]=0303;
536c2b["\304"]=0304; c2b["\305"]=0305; c2b["\306"]=0306; c2b["\307"]=0307;
537c2b["\310"]=0310; c2b["\311"]=0311; c2b["\312"]=0312; c2b["\313"]=0313;
538c2b["\314"]=0314; c2b["\315"]=0315; c2b["\316"]=0316; c2b["\317"]=0317;
539c2b["\320"]=0320; c2b["\321"]=0321; c2b["\322"]=0322; c2b["\323"]=0323;
540c2b["\324"]=0324; c2b["\325"]=0325; c2b["\326"]=0326; c2b["\327"]=0327;
541c2b["\330"]=0330; c2b["\331"]=0331; c2b["\332"]=0332; c2b["\333"]=0333;
542c2b["\334"]=0334; c2b["\335"]=0335; c2b["\336"]=0336; c2b["\337"]=0337;
543c2b["\340"]=0340; c2b["\341"]=0341; c2b["\342"]=0342; c2b["\343"]=0343;
544c2b["\344"]=0344; c2b["\345"]=0345; c2b["\346"]=0346; c2b["\347"]=0347;
545c2b["\350"]=0350; c2b["\351"]=0351; c2b["\352"]=0352; c2b["\353"]=0353;
546c2b["\354"]=0354; c2b["\355"]=0355; c2b["\356"]=0356; c2b["\357"]=0357;
547c2b["\360"]=0360; c2b["\361"]=0361; c2b["\362"]=0362; c2b["\363"]=0363;
548c2b["\364"]=0364; c2b["\365"]=0365; c2b["\366"]=0366; c2b["\367"]=0367;
549c2b["\370"]=0370; c2b["\371"]=0371; c2b["\372"]=0372; c2b["\373"]=0373;
550c2b["\374"]=0374; c2b["\375"]=0375; c2b["\376"]=0376; c2b["\377"]=0377;
551b2c = new Object();
552for (b in c2b) { b2c[c2b[b]] = b; }
553
554// ascii to 6-bit bin to ascii
555a2b = new Object();
556a2b["A"]=000; a2b["B"]=001; a2b["C"]=002; a2b["D"]=003;
557a2b["E"]=004; a2b["F"]=005; a2b["G"]=006; a2b["H"]=007;
558a2b["I"]=010; a2b["J"]=011; a2b["K"]=012; a2b["L"]=013;
559a2b["M"]=014; a2b["N"]=015; a2b["O"]=016; a2b["P"]=017;
560a2b["Q"]=020; a2b["R"]=021; a2b["S"]=022; a2b["T"]=023;
561a2b["U"]=024; a2b["V"]=025; a2b["W"]=026; a2b["X"]=027;
562a2b["Y"]=030; a2b["Z"]=031; a2b["a"]=032; a2b["b"]=033;
563a2b["c"]=034; a2b["d"]=035; a2b["e"]=036; a2b["f"]=037;
564a2b["g"]=040; a2b["h"]=041; a2b["i"]=042; a2b["j"]=043;
565a2b["k"]=044; a2b["l"]=045; a2b["m"]=046; a2b["n"]=047;
566a2b["o"]=050; a2b["p"]=051; a2b["q"]=052; a2b["r"]=053;
567a2b["s"]=054; a2b["t"]=055; a2b["u"]=056; a2b["v"]=057;
568a2b["w"]=060; a2b["x"]=061; a2b["y"]=062; a2b["z"]=063;
569a2b["0"]=064; a2b["1"]=065; a2b["2"]=066; a2b["3"]=067;
570a2b["4"]=070; a2b["5"]=071; a2b["6"]=072; a2b["7"]=073;
571a2b["8"]=074; a2b["9"]=075; a2b["+"]=076; a2b["_"]=077;
572
573b2a = new Object();
574for (b in a2b) { b2a[a2b[b]] = ''+b; }
575// -->
576</SCRIPT>
577EOT
578
579=pod
580
581=head1 NAME
582
583Tea.pm - The Tiny Encryption Algorithm in Perl and JavaScript
584
585=head1 SYNOPSIS
586
587Usage:
588
589 use Crypt::Tea;
590 $key = 'PUFgob$*LKDF D)(F IDD&P?/';
591 $ascii_ciphertext = &encrypt ($plaintext, $key);
592 ...
593 $plaintext_again = &decrypt ($ascii_ciphertext, $key);
594 ...
595 $signature = &asciidigest ($text);
596
597In CGI scripts:
598
599 use Crypt::Tea;
600 print &tea_in_javascript; # now the browser can encrypt
601 # and decrypt ! see CGI::Htauth.pm for examples ...
602
603=head1 DESCRIPTION
604
605This module implements TEA, the Tiny Encryption Algorithm,
606and some Modes of Use, in Perl and JavaScript.
607
608The $key is a sufficiently longish string; at least 17 random 8-bit
609bytes for single encryption.
610
611As of version 1.34, various Htauth-specific hook routines
612have now been moved out into the I<CGI::Htauth.pm> module.
613
614Version 1.43,
615#COMMENT#
616
617(c) Peter J Billam 1998
618
619=head1 SUBROUTINES
620
621=over 3
622
623=item I<encrypt>( $plaintext, $key );
624
625Encrypts with CBC (Cipher Block Chaining)
626
627=item I<decrypt>( $ciphertext, $key );
628
629Decrypts with CBC (Cipher Block Chaining)
630
631=item I<binary2ascii>( $a_binary_string );
632
633Provide an ascii text encoding of the binary argument.
634If Tea.pm is not being invoked from a GCI script,
635the ascii is split into lines of 72 characters.
636
637=item I<ascii2binary>( $an_ascii_string );
638
639=item I<asciidigest>( $a_string );
640
641Returns an asciified binary signature of the argument.
642
643=item I<tea_in_javascript>();
644
645Returns a compatible implementation of TEA in JavaScript,
646for use in CGI scripts to communicate with browsers.
647
648=back
649
650=head1 AUTHOR
651
652Peter J Billam <peter@pjb.com.au>,
653with thanks also to Neil Watkiss for MakeMaker packaging.
654
655=head1 CREDITS
656
657Based on TEA, as described in
658http://www.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html ,
659and on some help from I<Applied Cryptography> by Bruce Schneier
660as regards the modes of use.
661
662=head1 SEE ALSO
663
664http://www.pjb.com.au/, CGI::Htauth.pm, perl(1).
665
666=cut
667