1#!/usr/bin/perl -w
2#########################################################################
3#        This Perl script is Copyright (c) 2002, Peter J Billam         #
4#               c/o P J B Computing, www.pjb.com.au                     #
5#                                                                       #
6#     This script is free software; you can redistribute it and/or      #
7#            modify it under the same terms as Perl itself.             #
8#########################################################################
9
10use Test::Simple tests => 13;
11use Crypt::Tea_JS;
12use integer;
13
14my $text = <<'EOT';
15Hier lieg' ich auf dem Frülingshügel:
16die Wolke wird mein Flügel,
17ein Vogel fliegt mir voraus.
18
19Ach, sag' mir, all-einzige Liebe,
20wo du bleibst, daß ich bei dir bliebe !
21doch du und die Lüfte, ihr habt kein Haus.
22
23Der Sonnenblume gleich steht mein Gemüthe offen,
24sehnend, sich dehnend in Lieben und Hoffen.
25Frühling, was bist du gewillt ?
26wenn werd' ich gestillt ?
27
28Die Wolke seh' ich wandeln und den Fluß,
29es dringt der Sonne goldner Kuß tief bis in's Geblüt hinein;
30die Augen, wunderbar berauschet, thun, als scliefen sie ein,
31nur noch das Ohr der Ton der Biene lauschet.
32
33Ich denke Diess und denke Das,
34ich sehne mich, und weiss nicht recht, nach was:
35halb ist es Lust, halb ist es Klage;
36mein Herz, o sage,
37was webst du für Erinnerung
38in goldnen grüner Zweige Dämmerung ?
39
40Alte, unnennbare Tage !
41EOT
42
43ok (&Crypt::Tea_JS::binary2ascii(1234567,7654321,9182736,8273645)
44 eq "ABLWhwB0y7EAjB4QAH4-7Q", "binary2ascii");
45
46my @ary = &Crypt::Tea_JS::ascii2binary("GUQEX19vG3csxE9v2Vtwh");
47ok (&equal(\@ary,
48 [423887967, 1601117047, 751062895, 3646648452]), "ascii2binary");
49
50@ary = &Crypt::Tea_JS::oldtea_code((2048299521,595110280),
51  (032234174231,554905533,637549562,035705455446));
52ok (&equal(\@ary, [034504733200, 1589210186]), "oldtea_code");
53
54@ary = &Crypt::Tea_JS::oldtea_decode((2048299521,595110280),
55  (032234174231,554905533,637549562,035705455446));
56ok (&equal(\@ary, [036053034552, 023357663604]), "oldtea_decode");
57
58@ary = &Crypt::Tea_JS::pp_oldtea_code((2048299521,595110280),
59  (032234174231,554905533,637549562,035705455446));
60ok (&equal(\@ary, [034504733200, 1589210186]), "pp_oldtea_code");
61
62@ary = &Crypt::Tea_JS::pp_oldtea_decode((2048299521,595110280),
63  (032234174231,554905533,637549562,035705455446));
64ok (&equal(\@ary, [036053034552, 023357663604]), "pp_oldtea_decode");
65
66@ary = &Crypt::Tea_JS::tea_code((2048299521,595110280),
67  (032234174231,554905533,637549562,035705455446));
68ok (&equal(\@ary, [023450705615, 826873245]), "tea_code");
69
70@ary = &Crypt::Tea_JS::tea_decode((2048299521,595110280),
71  (032234174231,554905533,637549562,035705455446));
72ok (&equal(\@ary, [021317044354, 034350376361]), "tea_decode");
73
74@ary = &Crypt::Tea_JS::pp_tea_code((2048299521,595110280),
75  (032234174231,554905533,637549562,035705455446));
76ok (&equal(\@ary, [023450705615, 826873245]), "pp_tea_code");
77
78@ary = &Crypt::Tea_JS::pp_tea_decode((2048299521,595110280),
79  (032234174231,554905533,637549562,035705455446));
80ok (&equal(\@ary, [021317044354, 034350376361]), "pp_tea_decode");
81
82ok (&asciidigest($text) eq "7IGNTaSe2ch6WTwcz6c1eA", "asciidigest");
83
84my $key1 = &asciidigest ("G $$ ". time);
85my $c = &encrypt ($text, $key1);
86my $p = &decrypt ($c, $key1);
87ok (($p eq $text), "encrypt and decrypt");
88
89{
90	no integer;
91	if ($] > 5.007) {
92		require Encode;
93		$x = chr(400);
94		$c = &encrypt ($x, $key1);
95		$p = Encode::decode_utf8(&decrypt ($c, $key1));
96		ok (($p eq $x), "encrypt and decrypt utf8");
97	} else {
98		ok (1, "skipping utf8 test for perl version < 5.007");
99	}
100}
101
102&generate_test_html();
103
104exit;
105# --------------------------- infrastructure ----------------
106sub equal { my ($xref, $yref) = @_;
107	my $eps = .000000001;
108	my @x = @$xref; my @y = @$yref;
109	if (scalar @x != scalar @y) { return 0; }
110	my $i; for ($i=$[; $i<=$#x; $i++) {
111		if (abs($x[$i]-$y[$i]) > $eps) { return 0; }
112	}
113	return 1;
114}
115
116sub generate_test_html {
117$key1 = &asciidigest ("G $$ ". time);
118my $key2 = &asciidigest ("Arghhh... " . time ."Xgloopiegleep $$");
119
120my $p1 = <<EOT;
121If you are reading this paragraph, it has been successfully
122encrypted by <I>Perl</I> and decrypted by <I>JavaScript</I>.
123The password used was "$key1".
124A localised error in the cyphertext will cause about
12516 bytes of binary garbage to appear in the plaintext output.
126EOT
127my $p2 = <<EOT;
128And if you are reading this one, it has been successfully
129encrypted by <I>Perl</I>, decrypted by <I>JavaScript</I>,
130and then, using a different password "$key2",
131re-encrypted and re-decrypted by <I>JavaScript</I>.
132This means that <B>everyting&nbsp;works</B>&nbsp;:-)
133EOT
134
135if (! open (F, '>test.html')) { die "# sorry, can't write to test.html: $!\n"; }
136$ENV{REMOTE_ADDR} = '123.321.123.321';  # simulate CGI context
137my $c1 = &encrypt ($p1, $key1);
138my $c2 = &encrypt ($p2, $key1);
139print F "<HTML><HEAD><TITLE>test.html</TITLE>\n",&tea_in_javascript(),<<'EOT';
140</HEAD><BODY BGCOLOR="#FFFFFF">
141<P><H2>
142This page is a test of the JavaScript side of
143<A HREF="http://search.cpan.org/~pjb">Crypt::Tea_JS.pm</A>
144</H2></P>
145
146<HR>
147<H3>First a quick check of the various JavaScript functions . . .</H3>
148<P>If any of these functions do not return what they should,
149please use your mouse to cut-and-paste all the bit in
150<CODE>constant-width</CODE> font, and paste it into an email to
151<A HREF="http://www.pjb.com.au/comp/contact.html">Peter&nbsp;Billam</A>
152</P>
153<PRE>
154<SCRIPT LANGUAGE="JavaScript"> <!--
155EOT
156print F <<EOT;
157document.write('Crypt::Tea_JS ${Crypt::Tea_JS::VERSION} on ' + navigator.appName
158EOT
159print F <<'EOT';
160 + ' ' + navigator.appVersion);
161// -->
162</SCRIPT>
163
164binary2ascii(1234567,7654321,9182736,8273645)
165<SCRIPT LANGUAGE="JavaScript"> <!--
166var blocks = new Array();
167blocks[0]=1234567; blocks[1]=7654321; blocks[2]=9182736; blocks[3]=8273645;
168document.write('   returns ' + binary2ascii(blocks));
169// -->
170</SCRIPT>
171 should be ABLWhwB0y7EAjB4QAH4-7Q
172
173ascii2binary('GUQEX19vG3csxE9v2Vtwh') returns
174<SCRIPT LANGUAGE="JavaScript"> <!--
175var b = new Array; b = ascii2binary('GUQEX19vG3csxE9v2Vtwh');
176var ib = 0;  var lb = b.length;
177document.write('   returns ');
178while (1) {
179 if (ib >= lb) break;
180 document.write(b[ib] + ', ');
181 ib++;
182}
183// -->
184</SCRIPT>
185 should be 423887967, 1601117047, 751062895, -648318844,
186
187str2bytes('GUQEX19vG3csxE9')
188<SCRIPT LANGUAGE="JavaScript"> <!--
189var b = new Array; b = str2bytes('GUQEX19vG3csxE9');
190var ib = 0;  var lb = b.length;
191document.write('   returns ');
192while (1) {
193 if (ib >= lb) break;
194 document.write(b[ib] + ', ');
195 ib++;
196}
197// -->
198</SCRIPT>
199 should be 71, 85, 81, 69, 88, 49, 57, 118, 71, 51, 99, 115, 120, 69, 57,
200
201bytes2str(88, 49, 118, 99, 115, 69)
202<SCRIPT LANGUAGE="JavaScript"> <!--
203var b = new Array;
204b[0]=88; b[1]=49; b[2]=118; b[3]=99; b[4]=115; b[5]=69;
205document.write('   returns ' + bytes2str(b));
206// -->
207</SCRIPT>
208 should be X1vcsE
209
210ascii2bytes('GUQEX19vG3csxE9v2') returns
211<SCRIPT LANGUAGE="JavaScript"> <!--
212var b = new Array; b = ascii2bytes('GUQEX19vG3csxE9v2');
213var ib = 0;  var lb = b.length;
214document.write('   returns ');
215while (1) {
216 if (ib >= lb) break;
217 document.write(b[ib] + ', ');
218 ib++;
219}
220// -->
221</SCRIPT>
222 should be 25, 68, 4, 95, 95, 111, 27, 119, 44, 196, 79, 111, 216,
223
224bytes2str(88, 49, 118, 99, 115, 69)
225<SCRIPT LANGUAGE="JavaScript"> <!--
226var b = new Array;
227b[0]=88; b[1]=49; b[2]=118; b[3]=99; b[4]=115; b[5]=69;
228document.write('   returns ' + bytes2ascii(b));
229// -->
230</SCRIPT>
231 should be WDF2Y3NF
232
233bytes2blocks(88, 49, 118, 99, 115, 69)
234<SCRIPT LANGUAGE="JavaScript"> <!--
235var by = new Array;
236by[0]=88; by[1]=49; by[2]=118; by[3]=99; by[4]=115; by[5]=69;
237var bl = bytes2blocks(by); var ibl = 0;  var lbl = bl.length;
238document.write('   returns ');
239while (1) {
240 if (ibl >= lbl) break;
241 document.write(bl[ibl] + ', ');
242 ibl++;
243}
244// -->
245</SCRIPT>
246 should be 1479636579, 1933901824,
247
248digest_pad(88, 49, 118, 99, 115, 69)
249<SCRIPT LANGUAGE="JavaScript"> <!--
250var by = new Array;
251by[0]=88; by[1]=49; by[2]=118; by[3]=99; by[4]=115; by[5]=69;
252var bl = digest_pad(by); var ibl = 0;  var lbl = bl.length;
253document.write('   returns ');
254while (1) {
255 if (ibl >= lbl) break;
256 document.write(bl[ibl] + ', ');
257 ibl++;
258}
259// -->
260</SCRIPT>
261 should be 9, 88, 49, 118, 99, 115, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262
263pad(88, 49, 118, 99, 115, 69)
264<SCRIPT LANGUAGE="JavaScript"> <!--
265var by = new Array;
266by[0]=88; by[1]=49; by[2]=118; by[3]=99; by[4]=115; by[5]=69;
267var bl = pad(by); var ibl = 0;  var lbl = bl.length;
268document.write('   returns ');
269while (1) {
270 if (ibl >= lbl) break;
271 document.write(bl[ibl] + ', ');
272 ibl++;
273}
274// -->
275</SCRIPT>
276 should be ??, 88, 49, 118, 99, 115, 69, ??,
277 but note that the first and last bytes are random
278
279unpad(121, 88, 49, 118, 99, 115, 69, 162)
280<SCRIPT LANGUAGE="JavaScript"> <!--
281var by = new Array;
282by[0]=121;by[1]=88;by[2]=49;by[3]=118;by[4]=99;by[5]=115;by[6]=69;by[7]=162;
283var bl = unpad(by); var ibl = 0;  var lbl = bl.length;
284document.write('   returns ');
285while (1) {
286 if (ibl >= lbl) break;
287 document.write(bl[ibl] + ', ');
288 ibl++;
289}
290// -->
291</SCRIPT>
292 should be 88, 49, 118, 99, 115, 69,
293
294asciidigest('Gloop gleep glorp glurp')
295<SCRIPT LANGUAGE="JavaScript"> <!--
296document.write('   returns ' + asciidigest('Gloop gleep glorp glurp'));
297// -->
298</SCRIPT>
299 should be CygjbXoiuZ5g_O7F0MQG_A
300
301binarydigest('Gloop gleep glorp glurp', 'ksmZjyFSBRc3_cHLUag9zA')
302<SCRIPT LANGUAGE="JavaScript"> <!--
303var bl = binarydigest('Gloop gleep glorp glurp', 'ksmZjyFSBRc3_cHLUag9zA');
304var ibl = 0;  var lbl = bl.length;
305document.write('   returns ');
306while (1) {
307 if (ibl >= lbl) break;
308 document.write(bl[ibl] + ', ');
309 ibl++;
310}
311// -->
312</SCRIPT>
313 should be 187179885, 2049096094, 1627188933, -792459524,
314
315xor_blocks((2048299521, 595110280), (-764348263, -554905533))
316<SCRIPT LANGUAGE="JavaScript"> <!--
317var bl1 = new Array(); var bl2 = new Array();
318bl1[0]=2048299521; bl1[1]=595110280; bl2[0]=-764348263; bl2[1]=-554905533;
319var bl = xor_blocks(bl1,bl2);
320var ibl = 0;  var lbl = bl.length;
321document.write('   returns ');
322while (1) {
323 if (ibl >= lbl) break;
324 document.write(bl[ibl] + ', ');
325 ibl++;
326}
327// -->
328</SCRIPT>
329 should be -1469683048, -40601141,
330
331tea_code((2048299521,595110280),
332  (-764348263,554905533,637549562,-283747546))
333<SCRIPT LANGUAGE="JavaScript"> <!--
334var v = new Array(); var key = new Array();
335v[0]=2048299521; v[1]=595110280;
336key[0]=-764348263; key[1]=554905533;
337key[2]=637549562; key[3]=-283747546;
338var bl = tea_code(v,key);
339var ibl = 0;  var lbl = bl.length;
340document.write('   returns ');
341while (1) {
342 if (ibl >= lbl) break;
343 document.write(bl[ibl] + ', ');
344 ibl++;
345}
346// -->
347</SCRIPT>
348 should be -1667003507, 826873245,
349
350tea_decode((2048299521,595110280),
351  (-764348263,554905533,637549562,-283747546))
352<SCRIPT LANGUAGE="JavaScript"> <!--
353var v = new Array(); var key = new Array();
354v[0]=2048299521; v[1]=595110280;
355key[0]=-764348263; key[1]=554905533;
356key[2]=637549562; key[3]=-283747546;
357var bl = tea_decode(v,key);
358var ibl = 0;  var lbl = bl.length;
359document.write('   returns ');
360while (1) {
361 if (ibl >= lbl) break;
362 document.write(bl[ibl] + ', ');
363 ibl++;
364}
365// -->
366</SCRIPT>
367 should be -1958983444, -475923215,
368
369</PRE>
370
371EOT
372print F <<EOT;
373<HR><H3>Now a test of JavaScript decryption . . .</H3><P><FONT SIZE='+1'>
374<SCRIPT LANGUAGE="JavaScript"> <!--
375document.write(decrypt('$c1','$key1'));
376// -->
377</SCRIPT>
378</FONT></P>
379
380<HR><H3>Finally a test of JavaScript encryption . . .</H3><P><FONT SIZE='+1'>
381<SCRIPT LANGUAGE="JavaScript"> <!--
382var c2 = encrypt(decrypt('$c2','$key1'),'$key2');
383document.write(decrypt(c2,'$key2'));
384// -->
385</SCRIPT>
386</FONT></P>
387<HR></BODY></HTML>
388EOT
389close F;
390
391print "#      Now use a JavaScript-capable browser to view test.html ...\n";
392}
393
394__END__
395
396=pod
397
398=head1 NAME
399
400test.pl - Perl script to test Crypt::Tea_JS.pm
401
402=head1 SYNOPSIS
403
404  make test
405  netscape file:test.html
406
407=head1 DESCRIPTION
408
409This tests the Crypt::Tea_JS.pm module.
410
411=head1 AUTHOR
412
413Peter J Billam  http://www.pjb.com.au/comp/contact.html
414
415=head1 SEE ALSO
416
417http://www.pjb.com.au/ http://www.cpan.org perl(1).
418
419=cut
420
421
422