summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/srpproject/srp/views.py1
-rw-r--r--django/srpproject/templates/login.html6
-rw-r--r--django/srpproject/templates/register.html3
-rw-r--r--javascript/jsPacker/Pack.pm467
-rw-r--r--javascript/jsPacker/ParseMaster.pm207
-rw-r--r--javascript/jsPacker/build-pack.sh4
-rw-r--r--javascript/jsPacker/jsPacker.pl163
-rw-r--r--javascript/jsPacker/srp.min.js1
-rw-r--r--javascript/srp.js6
9 files changed, 853 insertions, 5 deletions
diff --git a/django/srpproject/srp/views.py b/django/srpproject/srp/views.py
index 1ad98dc..4200e8c 100644
--- a/django/srpproject/srp/views.py
+++ b/django/srpproject/srp/views.py
@@ -116,6 +116,7 @@ def verify(request):
response = "<M>%s</M>" % hashlib.sha256("%s%s%s" % (request.session["srp_A"], request.session["srp_M"], request.session["srp_S"])).hexdigest()
auth.login(request, user)
else:
+ # This should only happen when authentication is successful with SRP, but the user isn't in the auth table.
response = "<error>Authentication failed. This is likely a server problem.</error>"
else:
response = "<error>Invalid username or password.</error>"
diff --git a/django/srpproject/templates/login.html b/django/srpproject/templates/login.html
index f949663..6a77b2c 100644
--- a/django/srpproject/templates/login.html
+++ b/django/srpproject/templates/login.html
@@ -1,11 +1,13 @@
<html>
<head>
+ {% comment %}
<script src="{{ static_files }}/SHA256.js"></script>
<script src="{{ static_files }}/prng4.js"></script>
<script src="{{ static_files }}/rng.js"></script>
<script src="{{ static_files }}/jsbn.js"></script>
- <script src="{{ static_files }}/jsbn2.js"></script>
- <script src="{{ static_files }}/srp.js"></script>
+ <script src="{{ static_files }}/jsbn2.js"></script>{% endcomment %}
+ <script src="{{ static_files }}/jsPacker/srp.min.js"></script>
+
<script type="text/javascript">
function login()
{
diff --git a/django/srpproject/templates/register.html b/django/srpproject/templates/register.html
index 82ce61e..2119802 100644
--- a/django/srpproject/templates/register.html
+++ b/django/srpproject/templates/register.html
@@ -1,11 +1,14 @@
<html>
<head>
+ {% comment %}
<script src="{{ static_files }}/SHA256.js"></script>
<script src="{{ static_files }}/prng4.js"></script>
<script src="{{ static_files }}/rng.js"></script>
<script src="{{ static_files }}/jsbn.js"></script>
<script src="{{ static_files }}/jsbn2.js"></script>
<script src="{{ static_files }}/srp.js"></script>
+ {% endcomment %}
+ <script src="{{ static_files }}/jsPacker/srp.min.js"></script>
<script type="text/javascript">
function register()
{
diff --git a/javascript/jsPacker/Pack.pm b/javascript/jsPacker/Pack.pm
new file mode 100644
index 0000000..fbd2292
--- /dev/null
+++ b/javascript/jsPacker/Pack.pm
@@ -0,0 +1,467 @@
+#Pack (July 2005)
+# Based on "Pack.js" by Dean Edwards <http://dean.edwards.name/>
+# Ported to Perl by Rob Seiler, ELR Software Pty Ltd <http://www.elr.com.au>
+# Copyright 2005. License <http://creativecommons.org/licenses/LGPL/2.1/>
+
+package Pack;
+use strict;
+use Data::Dumper;
+
+use ParseMaster;
+
+# Package wide variable declarations
+use vars qw/$VERSION $PM_VERSION
+ $_X_encodePrivate $_JSunpack $_JSdecode %baseLookup
+ $_X_encode10 $_X_encode36 $_X_encode62 $_X_encode95
+ $_JSencode10 $_JSencode36 $_JSencode62 $_JSencode95
+ @_X_parsers
+ $_X_script $_X_encoding $_X_fastDecode $_X_specialChars
+ /;
+$VERSION = '024';
+$PM_VERSION = $ParseMaster::VERSION;
+
+# Package wide constants
+my $X_IGNORE = q{$1};
+my $X_ENCODE = q/\x24encode\(\x24count\)/; # NB: requires g modifier
+my $PERL = 'perl'; # Flag to indicate whether we need to use one of our "internal" Perl encoding functions
+my $JSCRIPT = 'jscript'; # or embed a pre-build JScript encoding function
+########################################
+
+##################
+sub pack($$$$) { # require 4 arguments
+##################
+#print Dumper(@_);
+ ($_X_script, $_X_encoding, $_X_fastDecode, $_X_specialChars) = @_;
+ # validate parameters (sort of!)
+ $_X_script .= "\n";
+ $_X_encoding = ($_X_encoding > 95) ? 95 : $_X_encoding;
+
+ @_X_parsers = (); # Reset parsers
+
+####################
+ sub _X_pack($) { # require 1 argument
+####################
+ # apply all parsing routines
+ my $X_script = shift;
+ for (my $i = 0; $i<scalar(@_X_parsers); $i++) {
+ my $X_parse = $_X_parsers[$i];
+ $X_script = &$X_parse($X_script);
+ }
+ return $X_script;
+ };
+
+######################
+ sub _X_addParser { #
+######################
+ # keep a list of parsing functions, they'll be executed all at once
+ my $X_parser = shift;
+ push (@_X_parsers,$X_parser);
+ }
+
+#############################
+ sub _X_basicCompression { #
+#############################
+ # zero encoding - just removal of white space and comments
+ my $X_script = shift;
+ my $parser = ParseMaster->new();
+ # make safe
+ $parser->escapeChar("\\");
+ # protect strings
+ $parser->add(q/'[^'\n\r]*'/, $X_IGNORE);
+ $parser->add(q/"[^"\n\r]*"/, $X_IGNORE);
+ # remove comments
+ $parser->add(q/\/\/[^\n\r]*[\n\r]/);
+ $parser->add(q/\/\*[^*]*\*+([^\/][^*]*\*+)*\//);
+ # protect regular expressions
+ $parser->add(q/\s+(\/[^\/\n\r\*][^\/\n\r]*\/g?i?)/, q{$2}); # IGNORE
+ $parser->add(q/[^\w\x24\/'"*)\?:]\/[^\/\n\r\*][^\/\n\r]*\/g?i?/, $X_IGNORE);
+ # remove: ;;; doSomething();
+ $parser->add(q/;;[^\n\r]+[\n\r]/) if ($_X_specialChars);
+ # remove redundant semi-colons
+ $parser->add(q/;+\s*([};])/, q{$2});
+ # remove white-space
+ $parser->add(q/(\b|\x24)\s+(\b|\x24)/, q{$2 $3});
+ $parser->add(q/([+\-])\s+([+\-])/, q{$2 $3});
+ $parser->add(q/\s+/, '');
+ # done
+ return $parser->exec($X_script);
+ }
+
+###############################
+ sub _X_encodeSpecialChars { #
+###############################
+ my $X_script = shift;
+ my $parser = ParseMaster->new();
+ # replace: $name -> n, $$name -> $$na
+ $parser->add(q/((\x24+)([a-zA-Z\x24_]+))(\d*)/,
+ sub {
+ my $X_offset = pop;
+ my @X_match = @_;
+ my $X_length = length($X_match[$X_offset+2]);
+ my $lengthnext = length($X_match[$X_offset+3]);
+ my $X_start = $X_length - ((($X_length - $lengthnext) > 0) ? ($X_length - $lengthnext) : 0);
+ my $str = $X_match[$X_offset+1];
+ $str = substr($str,$X_start,$X_length) . $X_match[$X_offset+4];
+ return "$str";
+ });
+ # replace: _name -> _0, double-underscore (__name) is ignored
+ my $X_regexp = q/\b_[A-Za-z\d]\w*/;
+ # build the word list
+ my %X_keywords = &_X_analyze($X_script, $X_regexp, $_X_encodePrivate);
+#print Dumper(%X_keywords);
+ # quick ref
+ my $X_encoded = \$X_keywords{X_encoded}; # eg _private1 => '_0',_private2 => '_1';
+#print Dumper($X_encoded);
+ $parser->add($X_regexp, sub {my $X_offset = pop; my @X_match = @_; return ${$X_encoded}->{$X_match[$X_offset]};});
+
+ return $parser->exec($X_script);
+ };
+
+###########################
+ sub _X_encodeKeywords { #
+###########################
+ my $X_script = shift;
+ # escape high-ascii values already in the script (i.e. in strings)
+ if ($_X_encoding > 62) {$X_script = &_X_escape95($X_script)};
+ # create the parser
+ my $parser = ParseMaster->new();
+ my $X_encode = &_X_getEncoder($_X_encoding,$PERL);
+ # for high-ascii, don't encode single character low-ascii
+ my $X_regexp = ($_X_encoding > 62) ? q/\w\w+/ : q/\w+/;
+ # build the word list
+ my %X_keywords = &_X_analyze($X_script, $X_regexp, $X_encode);
+#print Dumper(%X_keywords);
+ my $X_encoded = \$X_keywords{X_encoded}; # eg alert => 2, function => 10 etc
+ # encode
+ $parser->add($X_regexp, sub {my $X_offset = pop; my @X_match = @_; return ${$X_encoded}->{$X_match[$X_offset]};});
+ # if encoded, wrap the script in a decoding function
+
+ return $X_script && _X_bootStrap(\$parser->exec($X_script), \%X_keywords);
+ }
+
+####################
+ sub _X_analyze { #
+####################
+#print Dumper(@_);
+ my ($X_script, $X_regexp, $X_encode) = @_;
+ # analyse
+ # retreive all words in the script
+ my @X_all = $X_script =~ m/$X_regexp/g; # Save all captures in a list context
+ my %XX_sorted = (); # list of words sorted by frequency
+ my %XX_encoded = (); # dictionary of word->encoding
+ my %XX_protected = (); # instances of "protected" words
+ if (@X_all) {
+ my @X_unsorted = (); # same list, not sorted
+ my %X_protected = (); # "protected" words (dictionary of word->"word")
+ my %X_values = (); # dictionary of charCode->encoding (eg. 256->ff)
+ my %X_count = (); # word->count
+ my $i = scalar(@X_all); my $j = 0; my $X_word = '';
+ # count the occurrences - used for sorting later
+ do {
+ $X_word = '$' . $X_all[--$i];
+ if (!exists($X_count{$X_word})) {
+ $X_count{$X_word} = [0,$i]; # Store both the usage count and original array position (ie a secondary sort key)
+ $X_unsorted[$j] = $X_word;
+ # make a dictionary of all of the protected words in this script
+ # these are words that might be mistaken for encoding
+ $X_values{$j} = &$X_encode($j);
+ my $v = '$'.$X_values{$j};
+ $X_protected{$v} = $j++;
+ }
+ # increment the word counter
+ $X_count{$X_word}[0]++;
+ } while ($i);
+#print Dumper (%X_values);
+#print Dumper (@X_unsorted);
+#print Dumper (%X_protected);
+ # prepare to sort the word list, first we must protect
+ # words that are also used as codes. we assign them a code
+ # equivalent to the word itself.
+ # e.g. if "do" falls within our encoding range
+ # then we store keywords["do"] = "do";
+ # this avoids problems when decoding
+ $i = scalar(@X_unsorted);
+ do {
+ $X_word = $X_unsorted[--$i];
+ if (exists($X_protected{$X_word})) {
+ $XX_sorted{$X_protected{$X_word}} = substr($X_word,1);
+ $XX_protected{$X_protected{$X_word}} = 1; # true
+ $X_count{$X_word}[0] = 0;
+ }
+ } while ($i);
+#print Dumper (%XX_protected);
+#print Dumper (%XX_sorted);
+#print Dumper (%X_count);
+ # sort the words by frequency
+ # Sort with count a primary key and original array order as secondary key - which is apparently the default in javascript!
+ @X_unsorted = sort ({($X_count{$b}[0] - $X_count{$a}[0]) or ($X_count{$b}[1] <=> $X_count{$a}[1])} @X_unsorted);
+#print Dumper (@X_unsorted) . "\n";
+
+ $j = 0;
+ # because there are "protected" words in the list
+ # we must add the sorted words around them
+ do {
+ if (!exists($XX_sorted{$i})) {$XX_sorted{$i} = substr($X_unsorted[$j++],1)}
+ $XX_encoded{$XX_sorted{$i}} = $X_values{$i};
+ } while (++$i < scalar(@X_unsorted));
+ }
+#print Dumper(X_sorted => \%XX_sorted, X_encoded => \%XX_encoded, X_protected => \%XX_protected);
+ return (X_sorted => \%XX_sorted, X_encoded => \%XX_encoded, X_protected => \%XX_protected);
+ }
+
+######################
+ sub _X_bootStrap { #
+######################
+ # build the boot function used for loading and decoding
+ my ($X_packed, $X_keywords) = @_; # Reference arguments!
+#print Dumper ($X_keywords) . "\n";
+
+ # $packed: the packed script - dereference and escape
+ $X_packed = "'" . &_X_escape($$X_packed) ."'";
+
+ my %sorted = %{$$X_keywords{X_sorted}}; # Dereference to local variables
+ my %protected = %{$$X_keywords{X_protected}}; # for simplicity
+
+ my @sorted = ();
+ foreach my $key (keys %sorted) {$sorted[$key] = $sorted{$key}}; # Convert hash to a standard list
+
+ # ascii: base for encoding
+ my $X_ascii = ((scalar(@sorted) > $_X_encoding) ? $_X_encoding : scalar(@sorted)) || 1;
+
+ # count: number of (unique {RS}) words contained in the script
+ my $X_count = scalar(@sorted); # Use $X_count for assigning $X_ascii
+
+ # keywords: list of words contained in the script
+ foreach my $i (keys %protected) {$sorted[$i] = ''}; # Blank out protected words
+#print Dumper(@sorted) . "\n";
+
+ # convert from a string to an array - prepare keywords as a JScript string->array {RS}
+ $X_keywords = "'" . join('|',@sorted) . "'.split('|')";
+
+ # encode: encoding function (used for decoding the script)
+ my $X_encode = $_X_encoding > 62 ? $_JSencode95 : &_X_getEncoder($X_ascii,$JSCRIPT); # This is a JScript function (as a string)
+ $X_encode =~ s/_encoding/\x24ascii/g; $X_encode =~ s/arguments\.callee/\x24encode/g;
+ my $X_inline = '$count' . ($X_ascii > 10 ? '.toString($ascii)' : '');
+
+ # decode: code snippet to speed up decoding
+ my $X_decode = '';
+ if ($_X_fastDecode) {
+ # create the decoder
+ $X_decode = &_X_getFunctionBody($_JSdecode); # ie from the Javascript literal function
+ if ($_X_encoding > 62) {$X_decode =~ s/\\\\w/[\\xa1-\\xff]/g}
+ # perform the encoding inline for lower ascii values
+ elsif ($X_ascii < 36) {$X_decode =~ s/$X_ENCODE/$X_inline/g}
+ # special case: when $X_count==0 there ar no keywords. i want to keep
+ # the basic shape of the unpacking funcion so i'll frig the code...
+ if (!$X_count) {$X_decode =~ s/(\x24count)\s*=\s*1/$1=0/}
+ }
+
+ # boot function
+ my $X_unpack = $_JSunpack;
+ if ($_X_fastDecode) {
+ # insert the decoder
+ $X_unpack =~ s/\{/\{$X_decode;/;
+ }
+ $X_unpack =~ s/"/'/g;
+ if ($_X_encoding > 62) { # high-ascii
+ # get rid of the word-boundaries for regexp matches
+ $X_unpack =~ s/'\\\\b'\s*\+|\+\s*'\\\\b'//g; # Not checked! {RS}
+ }
+ if ($X_ascii > 36 || $_X_encoding > 62 || $_X_fastDecode) {
+ # insert the encode function
+ $X_unpack =~ s/\{/\{\$encode=$X_encode;/;
+ } else {
+ # perform the encoding inline
+ $X_unpack =~ s/$X_ENCODE/$X_inline/;
+ }
+
+ # arguments {RS} Do this before using &pack because &pack changes the pack parameters (eg $fastDecode) in Perl!!
+ my $X_params = "$X_packed,$X_ascii,$X_count,$X_keywords"; # Interpolate to comma separated string
+ if ($_X_fastDecode) {
+ # insert placeholders for the decoder
+ $X_params .= ',0,{}';
+ }
+
+ # pack the boot function too
+ $X_unpack = &pack($X_unpack,0,0,1);
+
+ # the whole thing
+ return "eval(" . $X_unpack . "(" . $X_params . "))\n";
+ };
+
+#######################
+ sub _X_getEncoder { #
+#######################
+ # mmm.. ..which one do i need ?? ({RS} Perl or JScript ??)
+ my ($X_ascii,$language) = @_;
+ my $perl_encoder = ($X_ascii > 10) ? ($X_ascii > 36) ? ($X_ascii > 62) ? $_X_encode95 : $_X_encode62 : $_X_encode36 : $_X_encode10;
+ my $jscript_encoder = ($X_ascii > 10) ? ($X_ascii > 36) ? ($X_ascii > 62) ? $_JSencode95 : $_JSencode62 : $_JSencode36 : $_JSencode10;
+ return ($language eq $JSCRIPT) ? $jscript_encoder : $perl_encoder;
+ };
+
+#############################
+# Perl versions of encoders #
+#############################
+ # base10 zero encoding - characters: 0123456789
+ $_X_encode10 = sub {return &_encodeBase(shift,10)};
+ # base36 - characters: 0123456789abcdefghijklmnopqrstuvwxyz
+ $_X_encode36 = sub {return &_encodeBase(shift,36)};
+ # base62 - characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ $_X_encode62 = sub {return &_encodeBase(shift,62)};
+ # high-ascii values - characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
+ $_X_encode95 = sub {return &_encodeBase(shift,95)};
+ # Lookup character sets for baseN encoding
+ $baseLookup{10} = [(0..9)[0..9]]; # base 10
+ $baseLookup{36} = [(0..9,'a'..'z')[0..35]]; # base 36
+ $baseLookup{62} = [(0..9,'a'..'z','A'..'Z')[0..61]]; # base 62
+ $baseLookup{95} = (); for (my $i=0; $i<95; $i++) {$baseLookup{95}[$i] = chr($i+161)}; # base95 (high ascii)
+#print Dumper(%baseLookup);
+#####################
+ sub _encodeBase { #
+#####################
+ # Generic base conversion function using defined lookup arrays (perl version only)
+ my ($X_charCode, $base) = @_;
+ my $X_encoded = '';
+ # Do we know this encoding?
+ if (exists ($baseLookup{$base})) {
+ if ($X_charCode == 0) {$X_encoded = $baseLookup{$base}[0]}
+ while($X_charCode > 0) {
+ $X_encoded = $baseLookup{$base}[$X_charCode % $base] . $X_encoded;
+ $X_charCode = int($X_charCode / $base);
+ }
+ }
+ else {$X_encoded = "$X_charCode"} # default is to return unchanged (ie as for base 10) if no baselookup is available
+ return $X_encoded;
+ };
+
+#############################
+ $_X_encodePrivate = sub { #
+#############################
+ # special _chars
+ my $X_charCode = shift;
+ return '_' . $X_charCode;
+ };
+
+############################
+ sub _X_escape($script) { #
+############################
+ # protect characters used by the parser
+ my $X_script = shift;
+ $X_script =~ s/([\\'])/\\$1/g;
+ return $X_script;
+ };
+
+#####################
+ sub _X_escape95 { #
+#####################
+ # protect high-ascii characters already in the script
+ my $X_script = shift;
+ $X_script =~ s/([\xa1-\xff])/sprintf("\\x%1x",ord($1))/eg;
+ return $X_script;
+ };
+
+############################
+ sub _X_getFunctionBody { #
+############################
+ # extract the body of a function (ie between opening/closing {}) - consistent with Dean Edwards approach
+ my $X_function = shift;
+ $X_function =~ m/^.*\{(.*)\}*$/sg; # Multiline, global (greedy)
+ my $start = index($X_function,'{');
+ my $end = rindex($X_function,'}');
+ $X_function = substr($X_function,($start+1),($end-1-$start));
+ return $X_function;
+ };
+
+######################
+ sub _X_globalize { #
+######################
+ # set the global flag on a RegExp (you have to create a new one) !!! Unused in perl version
+ # my $X_regexp = shift;
+ };
+
+ # build the parsing routine
+ &_X_addParser(\&_X_basicCompression);
+ &_X_addParser(\&_X_encodeSpecialChars) if ($_X_specialChars);
+ &_X_addParser(\&_X_encodeKeywords) if ($_X_encoding);
+
+ # go!
+ return &_X_pack($_X_script);
+}
+
+########################
+# Javascript Literals #
+########################
+
+# JScript function "_unpack" - from DeanEdwards pack.js (NB: No ";" after final "}")
+($_JSunpack) = <<'END_JSCRIPT_UNPACK';
+/* unpacking function - this is the boot strap function */
+/* data extracted from this packing routine is passed to */
+/* this function when decoded in the target */
+function($packed, $ascii, $count, $keywords, $encode, $decode) {
+ while ($count--)
+ if ($keywords[$count])
+ $packed = $packed.replace(new RegExp('\\b' + $encode($count) + '\\b', 'g'), $keywords[$count]);
+ /* RS_Debug = $packed; */ /* {RS} !!!!!!!!! */
+ return $packed;
+}
+END_JSCRIPT_UNPACK
+
+# JScript function "_decode" - from DeanEdwards pack.js
+($_JSdecode) = <<'END_JSCRIPT_DECODE';
+ /* code-snippet inserted into the unpacker to speed up decoding */
+ function() {
+ /* does the browser support String.replace where the */
+ /* replacement value is a function? */
+ if (!''.replace(/^/, String)) {
+ /* decode all the values we need */
+ while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);
+ /* global replacement function */
+ $keywords = [function($encoded){return $decode[$encoded]}];
+ /* generic match */
+ $encode = function(){return'\\w+'};
+ /* reset the loop counter - we are now doing a global replace */
+ $count = 1;
+ }
+ };
+END_JSCRIPT_DECODE
+
+# JScript versions of encoders
+($_JSencode10) = <<'END_JSCRIPT_ENCODE10';
+ /* zero encoding */
+ /* characters: 0123456789 */
+ function($charCode) {
+ return $charCode;
+ };
+END_JSCRIPT_ENCODE10
+
+($_JSencode36) = <<'END_JSCRIPT_ENCODE36';
+ /* inherent base36 support */
+ /* characters: 0123456789abcdefghijklmnopqrstuvwxyz */
+ function($charCode) {
+ return $charCode.toString(36);
+ };
+END_JSCRIPT_ENCODE36
+
+($_JSencode62) = <<'END_JSCRIPT_ENCODE62';
+ /* hitch a ride on base36 and add the upper case alpha characters */
+ /* characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ */
+ function($charCode) {
+ return ($charCode < _encoding ? '' : arguments.callee(parseInt($charCode / _encoding))) +
+ (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));
+ };
+END_JSCRIPT_ENCODE62
+
+($_JSencode95) = <<'END_JSCRIPT_ENCODE95';
+ /* use high-ascii values */
+ /* characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ */
+ function($charCode) {
+ return ($charCode < _encoding ? '' : arguments.callee($charCode / _encoding)) +
+ String.fromCharCode($charCode % _encoding + 161);
+ };
+END_JSCRIPT_ENCODE95
+
+###########
+# END #
+###########
+1; # Pack #
+###########
diff --git a/javascript/jsPacker/ParseMaster.pm b/javascript/jsPacker/ParseMaster.pm
new file mode 100644
index 0000000..f07ba68
--- /dev/null
+++ b/javascript/jsPacker/ParseMaster.pm
@@ -0,0 +1,207 @@
+#ParseMaster (July 25 2005)
+# Based on "ParseMaster.js" by Dean Edwards <http://dean.edwards.name/>
+# Ported to Perl by Rob Seiler, ELR Software Pty Ltd <http://www.elr.com.au>
+# Copyright 2005. License <http://creativecommons.org/licenses/LGPL/2.1/>
+
+package ParseMaster;
+use strict;
+use Data::Dumper;
+
+# Package wide variable declarations
+use vars qw/$VERSION
+ @_X_escaped @_X_patterns
+ /;
+
+$VERSION = '017';
+
+# constants
+my $X_EXPRESSION = 0;
+my $X_REPLACEMENT = 1;
+my $X_LENGTH = 2;
+
+# re's used to determine nesting levels
+my $X_GROUPS = qr/\(/o; # NB: Requires g modifier!
+my $X_SUB_REPLACE = qr/\$\d/o;
+my $X_INDEXED = qr/^\$\d+$/o;
+my $XX_ESCAPE = qr/\\./o; # NB: Requires g modifier!
+my $XX_DELETED = qr/\001[^\001]*\001/o; # NB: Requires g modifier!
+my $DIGIT = qr/[^\D]/o; # Yep - this is a digit - contains no non-digits
+
+# Constructor
+sub new {
+ my $class = shift;
+ my $self = {};
+ @_X_escaped = (); # Re-initialize global for each instance
+ @_X_patterns = (); # Re-initialize global for each instance
+ # Instance variables - access by similarly named set/get functions
+ $self->{_ignoreCase_} = 0;
+ $self->{_escapeChar_} = '';
+ bless ($self, $class);
+ return $self;
+}
+
+sub ignoreCase {
+ my ($self, $value) = @_;
+ if (defined($value)) {
+ $self->{_ignoreCase_} = $value;
+ }
+ return $self->{_ignoreCase_};
+}
+
+sub escapeChar{
+ my ($self, $value) = @_;
+ if (defined($value)) {
+ $self->{_escapeChar_} = $value;
+ }
+ return $self->{_escapeChar_};
+}
+
+#######################
+# Public Parsemaster functions
+
+my $X_DELETE = sub(@$) {
+ my $X_offset = pop;
+ my @X_match = @_;
+ return (chr(001) . $X_match[$X_offset] . chr(001));
+}; # NB semicolon required for closure!
+
+# create and add a new pattern to the patterns collection
+sub add {
+ my ($self, $expression, $X_replacement) = @_;
+ if (!$X_replacement) {$X_replacement = $X_DELETE};
+
+ # count the number of sub-expressions
+ my $temp = &_X_internalEscape($expression);
+ my $length = 1; # Always at least one because each pattern is itself a sub-expression
+ $length += $temp =~ s/$X_GROUPS//g; # One way to count the left capturing parentheses in the regexp string
+
+ # does the pattern deal with sub-expressions?
+ if ((ref($X_replacement) ne "CODE") && ($X_replacement =~ m/$X_SUB_REPLACE/)) {
+ if ($X_replacement =~ m/$X_INDEXED/) { # a simple lookup? (eg "$2")
+ # store the index (used for fast retrieval of matched strings)
+ $X_replacement = substr($X_replacement,1) - 1;
+ }
+ else { # a complicated lookup (eg "Hello $2 $1")
+ my $i = $length;
+ while ($i) { # Had difficulty getting Perl to do Dean's splitting and joining of strings containing $'s
+ my $str = '$a[$o+' . ($i-1) . ']'; # eg $a[$o+1]
+ $X_replacement =~ s/\$$i/$str/; # eg $2 $3 -> $a[$o+1] $a[$o+2]
+ $i--;
+ }
+ # build a function to do the lookup - returns interpolated string of array lookups
+ $X_replacement = eval('sub {my $o=pop; my @a=@_; return "' . $X_replacement . '"};');
+ }
+ }
+ else {}
+ # pass the modified arguments
+ &_X_add($expression || q/^$/, $X_replacement, $length);
+}
+
+# execute the global replacement
+sub exec {
+#print Dumper(@_X_patterns);
+ my ($self, $X_string) = @_;
+ my $escChar = $self->escapeChar();
+ my $ignoreCase = $self->ignoreCase();
+ my ($regexp,$captures) = &_getPatterns(); # Concatenated and parenthesized regexp eg '(regex1)|(regex2)|(regex3)' etc
+ $X_string = &_X_escape($X_string, $escChar);
+ if ($ignoreCase) {$X_string =~ s/$regexp/{&_X_replacement(&_matchVars($captures,\$X_string))}/gie} # Pass $X_String as a
+ else {$X_string =~ s/$regexp/{&_X_replacement(&_matchVars($captures,\$X_string))}/ge} # reference for speed
+
+ $X_string = &_X_unescape($X_string, $escChar);
+ $X_string =~ s/$XX_DELETED//g;
+ return $X_string;
+}
+
+sub _X_add {
+ push (@_X_patterns, [@_]); # Save each argument set as is into an array of arrays
+}
+
+# this is the global replace function (it's quite complicated)
+sub _X_replacement {
+ my (@arguments) = @_;
+#print Dumper (@arguments);
+ if ($arguments[0] le '') {return ''}
+ # Dereference last index (source String) here - faster than in _matchVars (maybe not needed at all?)
+ $arguments[$#arguments] = ${$arguments[$#arguments]};
+ my $i = 1;
+ # loop through the patterns
+ for (my $j=0; $j<scalar(@_X_patterns); $j++) { # Loop through global all @_X_patterns
+ my @X_pattern = @{$_X_patterns[$j]};
+ # do we have a result? NB: "if ($arguments[$i])" as in Dean's Javascript is false for the value 0!!!
+ if ((defined $arguments[$i]) && ($arguments[$i] gt '')) {
+ my $X_replacement = $X_pattern[$X_REPLACEMENT];
+ # switch on type of $replacement
+ if (ref($X_replacement) eq "CODE") { # function
+ return &$X_replacement(@arguments,$i);
+ }
+ elsif ($X_replacement =~ m/$DIGIT/) { # number (contains no non-digits)
+ return $arguments[$X_replacement + $i];
+ }
+ else { # default
+ return $X_replacement; # default
+ }
+ } # skip over references to sub-expressions
+ else {$i += $X_pattern[$X_LENGTH]}
+ }
+}
+
+#######################
+# Private functions
+#######################
+
+# encode escaped characters
+sub _X_escape {
+ my ($X_string, $X_escapeChar) = @_;
+ if ($X_escapeChar) {
+ my $re = '\\'.$X_escapeChar.'(.)';
+ $X_string =~ s/$re/{push(@_X_escaped,$1); $X_escapeChar}/ge;
+ }
+ return $X_string;
+}
+
+# decode escaped characters
+sub _X_unescape {
+ my ($X_string, $X_escapeChar) = @_;
+ if ($X_escapeChar) { # We'll only do this if there is an $X_escapeChar!
+ my $re = '\\'.$X_escapeChar;
+ $X_string =~ s/$re/{$X_escapeChar . (shift(@_X_escaped))}/ge; # Don't use Dean Edwards as below 'or' here - because zero will return ''!
+ # $X_string =~ s/$re/{$X_escapeChar . (shift(@_X_escaped) || '')}/ge;
+ }
+ return $X_string;
+}
+
+sub _X_internalEscape {
+ my ($string) = shift;
+ $string =~ s/$XX_ESCAPE//g;
+ return $string;
+}
+
+# Builds an array of match variables to (approximately) emulate that available in Javascript String.replace()
+sub _matchVars {
+ my ($m,$sref) = @_;
+ my @args = (1..$m); # establish the number potential memory variables
+ my @mv = map {eval("\$$_")} @args; # matchvarv[1..m] = the memory variables $1 .. $m
+ unshift (@mv, $&); # matchvar[0] = the substring that matched
+ push (@mv, length($`)); # matchvar[m+1] = offset within the source string where the match occurred (= length of prematch string)
+ push (@mv, $sref); # matchvar[m+2] = reference to full source string (dereference in caller if/when needed)
+#print Dumper (@mv);
+ return @mv;
+}
+
+sub _getPatterns {
+ my @Patterns = ();
+ my $lcp = 0;
+ for (my $i=0; $i<scalar(@_X_patterns); $i++) { # Loop through global all @_patterns
+ push (@Patterns, $_X_patterns[$i][$X_EXPRESSION]); # accumulate the expressions
+ $lcp += $_X_patterns[$i][$X_LENGTH]; # sum the left capturing parenthesis counts
+ }
+ my $str = "(" . join(')|(',@Patterns). ")"; # enclose each pattern in () separated by "|"
+ return ($str, $lcp);
+}
+
+##################
+# END #
+##################
+1; # ParseMaster #
+##################
diff --git a/javascript/jsPacker/build-pack.sh b/javascript/jsPacker/build-pack.sh
new file mode 100644
index 0000000..904b2ee
--- /dev/null
+++ b/javascript/jsPacker/build-pack.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+cat ../SHA256.js ../prng4.js ../rng.js ../jsbn.js ../jsbn2.js ../srp.js > utils.js
+perl jsPacker.pl -fsq -e62 -i utils.js -o srp.min.js
+rm utils.js
diff --git a/javascript/jsPacker/jsPacker.pl b/javascript/jsPacker/jsPacker.pl
new file mode 100644
index 0000000..80f7236
--- /dev/null
+++ b/javascript/jsPacker/jsPacker.pl
@@ -0,0 +1,163 @@
+#!perl
+#jsPacker (July 2005)
+#
+use strict;
+use Pack;
+use vars qw($PROGNAME $VERSION
+ $opt_h $opt_q $opt_v $opt_i $opt_o $opt_e $opt_f $opt_s);
+use Getopt::Std;
+
+$PROGNAME = $0;
+$VERSION = '1.00b';
+
+my $Description = 'A JavaScript Compressor/Obfuscator';
+my $Version = "v$VERSION\[p$Pack::VERSION-pm$Pack::PM_VERSION\]";
+
+# "English" versions of settings
+my %ENCODINGS = (0=>'None', 10=>'Decimal', 36=>'Normal', 62=>'Normal', 95=>'High-ascii');
+my %SETTINGS = (0=>'No', 1=>'Yes');
+
+exit(0) if &main();
+exit(1);
+
+################
+# Sub-routines #
+################
+# Main program
+sub main {
+ # Get command line options
+ &getopts('hqvfsi:o:e:');
+ $opt_h ||= 0; # $opt_h shows usage and exits
+ $opt_q ||= 0; # $opt_q sets quiet mode (no stdout output)
+ $opt_v ||= 0; # $opt_v shows version and exits
+ $opt_i ||= ''; # $opt_i is input file. Required!
+ $opt_o ||= ''; # $opt_o is output file. If not set, use standard output
+ $opt_e ||= 0; # $opt_e encoding level (0,10,36,62,95)
+ $opt_f ||= 0; # $opt_f use fast decoding
+ $opt_s ||= 0; # $opt_x use special characters
+
+ # Display help or version if requested
+ if ($opt_h) {&usage("help")}
+ if ($opt_v) {&usage("version")}
+
+ # Constrain encoding level, fastdecoding and specialcharacters to allowed limits
+ $opt_e = ($opt_e > 0) ? ($opt_e > 10) ? ($opt_e > 36) ? ($opt_e > 62) ? 95 : 62 : 36 : 10 : 0;
+ $opt_f = ($opt_f) ? 1 : 0;
+ $opt_s = ($opt_s) ? 1 : 0;
+
+ # Do the job if an input file is specified
+ if ($opt_i) {
+ # Read the source script
+ my $script = &readInputFile($opt_i);
+ # Pack the source script
+ my $packedscript = &Pack::pack($script,$opt_e, $opt_f, $opt_s);
+ # Show what happened (if not in quiet mode)
+ if (!$opt_q) {showJobDetails($opt_i, $opt_o, $opt_e, $opt_f,$opt_s,\$script,\$packedscript)}
+ # Output the packed script
+ if ($opt_o) {&writeOutputFile($opt_o,\$packedscript)} # to output file if specifed
+ else {print "$packedscript"} # otherwise to STDOUT
+ }
+ else { # If no input file is specified, display help
+ &usage();
+ }
+ return(1);
+}
+
+######################
+sub showJobDetails { #
+######################
+# Show details of input/output files, settings and compression ratio
+ my ($inputfile, $outputfile,
+ $encoding, $fastdecode, $specialchars,
+ $instringref, $outstringref) = @_;
+ print "$PROGNAME $Version\n";
+ print "\tSource file : ";
+ print "\"$inputfile\"\n";
+ print (($outputfile) ? ("\tOutput file : \"$outputfile\"\n") : ''); # Print only if output is going to a file
+ print "\tSettings : encoding=$ENCODINGS{$encoding} fastdecode=$SETTINGS{$fastdecode} specialchars=$SETTINGS{$specialchars}\n";
+ print "\tCompression : " . &compressionRatio($instringref, $outstringref). "\n\n";
+
+}
+
+#####################
+sub readInputFile { #
+#####################
+# Read content (source script) from input file
+ my $filename = shift;
+ open(FH, $filename) || die "Error!!! Problem opening input file \"$filename\"!\n";
+ my @content = <FH>;
+ close(FH);
+ return join('',@content);
+}
+
+#######################
+sub writeOutputFile { #
+#######################
+# Write content (packed script) to output file
+ my ($filename,$refcontent) = @_;
+ open(FH, ">$filename") || die "Error!!! Problem opening output file \"$filename\"\n";
+ print(FH $$refcontent);
+ close(FH);
+}
+
+########################
+sub compressionRatio { #
+########################
+# Calculate the ratio of output string to input string
+ my ($sref1,$sref2) = @_;
+ my $ratio = (length($$sref2) / (length($$sref1)||1));
+ $ratio = sprintf "%.2f", $ratio;
+ return $ratio;
+}
+
+#############
+sub usage { #
+#############
+# Inform user about usage, version and exit
+ my $showusage = 0;
+ my $showversion = 0;
+ my $params = shift;
+ if (defined $params) {
+ if ($params eq "help") {$showusage = 1;}
+ elsif ($params eq "version") {$showversion = 1;}
+ else {$showusage = 1;}
+ }
+ else {$showversion = 1;}
+ if ($showversion) {
+ print<<EOT;
+
+$PROGNAME $Version
+ $Description
+\tBased on "Packer.js" by Dean Edwards <http://dean.edwards.name/>
+\tPorted to Perl by Rob Seiler, ELR Software Pty Ltd <http://www.elr.com.au>
+\tCopyright 2005. License <http://creativecommons.org/licenses/LGPL/2.1/>
+ Use "$PROGNAME -h" for options
+EOT
+ exit(1);
+ }
+ if ($showusage) {
+ print<<EOT;
+
+$PROGNAME $Version
+ $Description
+ Usage:
+\t$PROGNAME -i inputfile [-o outputfile] [-eX] [-f] [-s] [-qvh]\n
+\t-i <inputfile> (eg -i myscript.js)
+\t-o <outputfile> (eg -o myscript-p.js)
+\t-eN <encoding> [0=None 10=Numeric 62=Normal(alphanumeric) 95=High-ascii]
+\t-f <fast decode>
+\t-s <special characters>
+\t-q quiet mode
+\t-v version
+\t-h help
+
+ Examples:
+\t$PROGNAME -i myscript.js
+\t$PROGNAME -i myscript.js -o packed.js
+\t$PROGNAME -i myscript.js -o packed.js -e10 -f -s
+\t$PROGNAME -i myscript.js -e95 -fsq > packed.js
+
+EOT
+ exit(1);
+ }
+}
diff --git a/javascript/jsPacker/srp.min.js b/javascript/jsPacker/srp.min.js
new file mode 100644
index 0000000..2ed2651
--- /dev/null
+++ b/javascript/jsPacker/srp.min.js
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('E 1E(s){C 2p=8;C 6R=0;E 1e(x,y){C 42=(x&40)+(y&40);C 6Z=(x>>16)+(y>>16)+(42>>16);F(6Z<<16)|(42&40)}E S(X,n){F(X>>>n)|(X<<(32-n))}E R(X,n){F(X>>>n)}E 6V(x,y,z){F((x&y)^((~x)&z))}E 6T(x,y,z){F((x&y)^(x&z)^(y&z))}E 6U(x){F(S(x,2)^S(x,13)^S(x,22))}E 6W(x){F(S(x,6)^S(x,11)^S(x,25))}E 6X(x){F(S(x,7)^S(x,18)^R(x,3))}E 6Y(x){F(S(x,17)^S(x,19)^R(x,10))}E 6N(m,l){C K=U 1x(aD,aC,aB,aA,az,ay,ax,aw,av,au,at,as,ar,aq,ap,ao,an,al,ak,aj,ai,ah,ag,af,ae,ad,ab,aa,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0,9Z,9Y,9X,9W,9V,9U,9T,9S,9R,9Q,9P,9O,9N,9M,9L,9K,9J,9I,9H,9G,9F,9E,9D,9C,9B,9A);C 1a=U 1x(9z,9y,9x,9w,9v,9u,9t,9s);C W=U 1x(64);C a,b,c,d,e,f,g,h,i,j;C 3h,3Z;m[l>>5]|=2I<<(24-l%32);m[((l+64>>9)<<4)+15]=l;P(C i=0;i<m.Z;i+=16){a=1a[0];b=1a[1];c=1a[2];d=1a[3];e=1a[4];f=1a[5];g=1a[6];h=1a[7];P(C j=0;j<64;j++){D(j<16)W[j]=m[j+i];J W[j]=1e(1e(1e(6Y(W[j-2]),W[j-7]),6X(W[j-15])),W[j-16]);3h=1e(1e(1e(1e(h,6W(e)),6V(e,f,g)),K[j]),W[j]);3Z=1e(6U(a),6T(a,b,c));h=g;g=f;f=e;e=1e(d,3h);d=c;c=b;b=a;a=1e(3h,3Z)}1a[0]=1e(a,1a[0]);1a[1]=1e(b,1a[1]);1a[2]=1e(c,1a[2]);1a[3]=1e(d,1a[3]);1a[4]=1e(e,1a[4]);1a[5]=1e(f,1a[5]);1a[6]=1e(g,1a[6]);1a[7]=1e(h,1a[7])}F 1a}E 6M(1M){C 3Y=1x();C 6S=(1<<2p)-1;P(C i=0;i<1M.Z*2p;i+=2p){3Y[i>>5]|=(1M.1Z(i/2p)&6S)<<(24-i%32)}F 3Y}E 6P(2o){2o=2o.9r(/\\r\\n/g,"\\n");C 1Q="";P(C n=0;n<2o.Z;n++){C c=2o.1Z(n);D(c<3g){1Q+=2r.2q(c)}J D((c>5x)&&(c<9q)){1Q+=2r.2q((c>>6)|9p);1Q+=2r.2q((c&63)|3g)}J{1Q+=2r.2q((c>>12)|9o);1Q+=2r.2q(((c>>6)&63)|3g);1Q+=2r.2q((c&63)|3g)}}F 1Q}E 6O(3f){C 3X=6R?"9n":"9m";C 1M="";P(C i=0;i<3f.Z*4;i++){1M+=3X.2K((3f[i>>2]>>((3-i%4)*8+4))&6Q)+3X.2K((3f[i>>2]>>((3-i%4)*8))&6Q)}F 1M}s=6P(s);F 6O(6N(6M(s),s.Z*2p))}E 3e(){o.i=0;o.j=0;o.S=U 1x()}E 6L(2s){C i,j,t;P(i=0;i<1P;++i)o.S[i]=i;j=0;P(i=0;i<1P;++i){j=(j+o.S[i]+2s[i%2s.Z])&1D;t=o.S[i];o.S[i]=o.S[j];o.S[j]=t}o.i=0;o.j=0}E 6K(){C t;o.i=(o.i+1)&1D;o.j=(o.j+o.S[o.i])&1D;t=o.S[o.i];o.S[o.i]=o.S[o.j];o.S[o.j]=t;F o.S[(t+o.S[o.i])&1D]}3e.H.6F=6L;3e.H.6E=6K;E 6G(){F U 3e()}C 3d=1P;C 2O;C 1p;C 1f;E 6J(x){1p[1f++]^=x&1D;1p[1f++]^=(x>>8)&1D;1p[1f++]^=(x>>16)&1D;1p[1f++]^=(x>>24)&1D;D(1f>=3d)1f-=3d}E 3W(){6J(U 9l().9k())}D(1p==Y){1p=U 1x();1f=0;C t;D(3c.3S=="6y"&&3c.9j<"5"&&2X.6I){C z=2X.6I.6H(32);P(t=0;t<z.Z;++t)1p[1f++]=z.1Z(t)&1D}L(1f<3d){t=1d.1W(9i*1d.6H());1p[1f++]=t>>>8;1p[1f++]=t&1D}1f=0;3W();}E 6D(){D(2O==Y){3W();2O=6G();2O.6F(1p);P(1f=0;1f<1p.Z;++1f)1p[1f]=0;1f=0;}F 2O.6E()}E 6C(3V){C i;P(i=0;i<3V.Z;++i)3V[i]=6D()}E 3t(){}3t.H.5J=6C;C 1L;C 6B=9h;C 3T=((6B&9g)==9f);E G(a,b,c){D(a!=Y)D("5K"==3J a)o.3x(a,b,c);J D(b==Y&&"2o"!=3J a)o.35(a,1P);J o.35(a,b)}E Q(){F U G(Y)}E 6x(i,x,w,j,c,n){L(--n>=0){C v=x*o[i++]+w[j]+c;c=1d.1W(v/9e);w[j++]=v&9d}F c}E 6z(i,x,w,j,c,n){C 2n=x&2L,2m=x>>15;L(--n>=0){C l=o[i]&2L;C h=o[i++]>>15;C m=2m*l+h*2n;l=2n*l+((m&2L)<<15)+w[j]+(c&6A);c=(l>>>30)+(m>>>15)+2m*h+(c>>>30);w[j++]=l&6A}F c}E 6w(i,x,w,j,c,n){C 2n=x&3U,2m=x>>14;L(--n>=0){C l=o[i]&3U;C h=o[i++]>>14;C m=2m*l+h*2n;l=2n*l+((m&3U)<<14)+w[j]+c;c=(l>>28)+(m>>14)+2m*h;w[j++]=l&9c}F c}D(3T&&(3c.3S=="4o 9b 9a")){G.H.am=6z;1L=30}J D(3T&&(3c.3S!="6y")){G.H.am=6x;1L=26}J{G.H.am=6w;1L=28}G.H.O=1L;G.H.1g=((1<<1L)-1);G.H.1k=(1<<1L);C 3b=52;G.H.6u=1d.2y(2,3b);G.H.3Q=3b-1L;G.H.3O=2*1L-3b;C 6v="99";C 2N=U 1x();C 20,1o;20="0".1Z(0);P(1o=0;1o<=9;++1o)2N[20++]=1o;20="a".1Z(0);P(1o=10;1o<36;++1o)2N[20++]=1o;20="A".1Z(0);P(1o=10;1o<36;++1o)2N[20++]=1o;E 3R(n){F 6v.2K(n)}E 3K(s,i){C c=2N[s.1Z(i)];F(c==Y)?-1:c}E 6c(r){P(C i=o.t-1;i>=0;--i)r[i]=o[i];r.t=o.t;r.s=o.s}E 6b(x){o.t=1;o.s=(x<0)?-1:0;D(x>0)o[0]=x;J D(x<-1)o[0]=x+1k;J o.t=0}E 1I(i){C r=Q();r.2d(i);F r}E 6a(s,b){C k;D(b==16)k=4;J D(b==8)k=3;J D(b==1P)k=8;J D(b==2)k=1;J D(b==32)k=5;J D(b==4)k=2;J{o.5r(s,b);F}o.t=0;o.s=0;C i=s.Z,1X=1s,1n=0;L(--i>=0){C x=(k==8)?s[i]&2H:3K(s,i);D(x<0){D(s.2K(i)=="-")1X=1F;5L}1X=1s;D(1n==0)o[o.t++]=x;J D(1n+k>o.O){o[o.t-1]|=(x&((1<<(o.O-1n))-1))<<1n;o[o.t++]=(x>>(o.O-1n))}J o[o.t-1]|=x<<1n;1n+=k;D(1n>=o.O)1n-=o.O}D(k==8&&(s[0]&2I)!=0){o.s=-1;D(1n>0)o[o.t-1]|=((1<<(o.O-1n))-1)<<1n}o.1l();D(1X)G.1w.V(o,o)}E 69(){C c=o.s&o.1g;L(o.t>0&&o[o.t-1]==c)--o.t}E 5S(b){D(o.s<0)F"-"+o.2B().1u(b);C k;D(b==16)k=4;J D(b==8)k=3;J D(b==2)k=1;J D(b==32)k=5;J D(b==4)k=2;J F o.5t(b);C 2D=(1<<k)-1,d,m=1s,r="",i=o.t;C p=o.O-(i*o.O)%k;D(i-->0){D(p<o.O&&(d=o[i]>>p)>0){m=1F;r=3R(d)}L(i>=0){D(p<k){d=(o[i]&((1<<p)-1))<<(k-p);d|=o[--i]>>(p+=o.O-k)}J{d=(o[i]>>(p-=k))&2D;D(p<=0){p+=o.O;--i}}D(d>0)m=1F;D(m)r+=3R(d)}}F m?r:"0"}E 5R(){C r=Q();G.1w.V(o,r);F r}E 5Q(){F(o.s<0)?o.2B():o}E 5P(a){C r=o.s-a.s;D(r!=0)F r;C i=o.t;r=i-a.t;D(r!=0)F r;L(--i>=0)D((r=o[i]-a[i])!=0)F r;F 0}E 2E(x){C r=1,t;D((t=x>>>16)!=0){x=t;r+=16}D((t=x>>8)!=0){x=t;r+=8}D((t=x>>4)!=0){x=t;r+=4}D((t=x>>2)!=0){x=t;r+=2}D((t=x>>1)!=0){x=t;r+=1}F r}E 5O(){D(o.t<=0)F 0;F o.O*(o.t-1)+2E(o[o.t-1]^(o.s&o.1g))}E 68(n,r){C i;P(i=o.t-1;i>=0;--i)r[i+n]=o[i];P(i=n-1;i>=0;--i)r[i]=0;r.t=o.t+n;r.s=o.s}E 66(n,r){P(C i=n;i<o.t;++i)r[i-n]=o[i];r.t=1d.3u(o.t-n,0);r.s=o.s}E 65(n,r){C 1C=n%o.O;C 2l=o.O-1C;C 2M=(1<<2l)-1;C 1m=1d.1W(n/o.O),c=(o.s<<1C)&o.1g,i;P(i=o.t-1;i>=0;--i){r[i+1m+1]=(o[i]>>2l)|c;c=(o[i]&2M)<<1C}P(i=1m-1;i>=0;--i)r[i]=0;r[1m]=c;r.t=o.t+1m+1;r.s=o.s;r.1l()}E 62(n,r){r.s=o.s;C 1m=1d.1W(n/o.O);D(1m>=o.t){r.t=0;F}C 1C=n%o.O;C 2l=o.O-1C;C 2M=(1<<1C)-1;r[0]=o[1m]>>1C;P(C i=1m+1;i<o.t;++i){r[i-1m-1]|=(o[i]&2M)<<2l;r[i-1m]=o[i]>>1C}D(1C>0)r[o.t-1m-1]|=(o.s&2M)<<2l;r.t=o.t-1m;r.1l()}E 60(a,r){C i=0,c=0,m=1d.2a(a.t,o.t);L(i<m){c+=o[i]-a[i];r[i++]=c&o.1g;c>>=o.O}D(a.t<o.t){c-=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1g;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c-=a[i];r[i++]=c&o.1g;c>>=o.O}c-=a.s}r.s=(c<0)?-1:0;D(c<-1)r[i++]=o.1k+c;J D(c>0)r[i++]=c;r.t=i;r.1l()}E 5Z(a,r){C x=o.1H(),y=a.1H();C i=x.t;r.t=i+y.t;L(--i>=0)r[i]=0;P(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.1l();D(o.s!=a.s)G.1w.V(r,r)}E 5Y(r){C x=o.1H();C i=r.t=2*x.t;L(--i>=0)r[i]=0;P(i=0;i<x.t-1;++i){C c=x.am(i,x[i],r,2*i,0,1);D((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.1k){r[i+x.t]-=x.1k;r[i+x.t+1]=1}}D(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.1l()}E 5X(m,q,r){C 1Y=m.1H();D(1Y.t<=0)F;C 3a=o.1H();D(3a.t<1Y.t){D(q!=Y)q.2d(0);D(r!=Y)o.1J(r);F}D(r==Y)r=Q();C y=Q(),3N=o.s,6r=m.s;C 2k=o.O-2E(1Y[1Y.t-1]);D(2k>0){1Y.2e(2k,y);3a.2e(2k,r)}J{1Y.1J(y);3a.1J(r)}C 1B=y.t;C 39=y[1B-1];D(39==0)F;C 3P=39*(1<<o.3Q)+((1B>1)?y[1B-2]>>o.3O:0);C 6t=o.6u/3P,6s=(1<<o.3Q)/3P,e=1<<o.3O;C i=r.t,j=i-1B,t=(q==Y)?Q():q;y.2i(j,t);D(r.1c(t)>=0){r[r.t++]=1;r.V(t,r)}G.1v.2i(1B,t);t.V(y,y);L(y.t<1B)y[y.t++]=0;L(--j>=0){C 38=(r[--i]==39)?o.1g:1d.1W(r[i]*6t+(r[i-1]+e)*6s);D((r[i]+=y.am(0,38,r,j,0,1B))<38){y.2i(j,t);r.V(t,r);L(r[i]<--38)r.V(t,r)}}D(q!=Y){r.2G(1B,q);D(3N!=6r)G.1w.V(q,q)}r.t=1B;r.1l();D(2k>0)r.1h(2k,r);D(3N<0)G.1w.V(r,r)}E 5N(a){C r=Q();o.1H().1K(a,Y,r);D(o.s<0&&r.1c(G.1w)>0)a.V(r,r);F r}E 1O(m){o.m=m}E 6q(x){D(x.s<0||x.1c(o.m)>=0)F x.3D(o.m);J F x}E 6p(x){F x}E 6o(x){x.1K(o.m,Y,x)}E 6n(x,y,r){x.2h(y,r);o.1y(r)}E 6m(x,r){x.2F(r);o.1y(r)}1O.H.2g=6q;1O.H.2f=6p;1O.H.1y=6o;1O.H.1T=6n;1O.H.1A=6m;E 5V(){D(o.t<1)F 0;C x=o[0];D((x&1)==0)F 0;C y=x&3;y=(y*(2-(x&3I)*y))&3I;y=(y*(2-(x&2H)*y))&2H;y=(y*(2-(((x&34)*y)&34)))&34;y=(y*(2-x*y%o.1k))%o.1k;F(y>0)?o.1k-y:-y}E 1N(m){o.m=m;o.3M=m.5W();o.3L=o.3M&2L;o.6k=o.3M>>15;o.6j=(1<<(m.O-15))-1;o.6l=2*m.t}E 6h(x){C r=Q();x.1H().2i(o.m.t,r);r.1K(o.m,Y,r);D(x.s<0&&r.1c(G.1w)>0)o.m.V(r,r);F r}E 6g(x){C r=Q();x.1J(r);o.1y(r);F r}E 6f(x){L(x.t<=o.6l)x[x.t++]=0;P(C i=0;i<o.m.t;++i){C j=x[i]&2L;C 6i=(j*o.3L+(((j*o.6k+(x[i]>>15)*o.3L)&o.6j)<<15))&x.1g;j=i+o.m.t;x[j]+=o.m.am(0,6i,x,i,0,o.m.t);L(x[j]>=x.1k){x[j]-=x.1k;x[++j]++}}x.1l();x.2G(o.m.t,x);D(x.1c(o.m)>=0)x.V(o.m,x)}E 6d(x,r){x.2F(r);o.1y(r)}E 6e(x,y,r){x.2h(y,r);o.1y(r)}1N.H.2g=6h;1N.H.2f=6g;1N.H.1y=6f;1N.H.1T=6e;1N.H.1A=6d;E 5U(){F((o.t>0)?(o[0]&1):o.s)==0}E 5T(e,z){D(e>98||e<1)F G.1v;C r=Q(),1b=Q(),g=z.2g(o),i=2E(e)-1;g.1J(r);L(--i>=0){z.1A(r,1b);D((e&(1<<i))>0)z.1T(1b,g,r);J{C t=r;r=1b;1b=t}}F z.2f(r)}E 5M(e,m){C z;D(e<1P||m.1j())z=U 1O(m);J z=U 1N(m);F o.3E(e,z)}G.H.1J=6c;G.H.2d=6b;G.H.35=6a;G.H.1l=69;G.H.2i=68;G.H.2G=66;G.H.2e=65;G.H.1h=62;G.H.V=60;G.H.2h=5Z;G.H.2F=5Y;G.H.1K=5X;G.H.5W=5V;G.H.1j=5U;G.H.3E=5T;G.H.1u=5S;G.H.2B=5R;G.H.1H=5Q;G.H.1c=5P;G.H.3B=5O;G.H.3D=5N;G.H.5v=5M;G.1w=1I(0);G.1v=1I(1);E 5b(){C r=Q();o.1J(r);F r}E 5a(){D(o.s<0){D(o.t==1)F o[0]-o.1k;J D(o.t==0)F-1}J D(o.t==1)F o[0];J D(o.t==0)F 0;F((o[1]&((1<<(32-o.O))-1))<<o.O)|o[0]}E 58(){F(o.t==0)?o.s:(o[0]<<24)>>24}E 57(){F(o.t==0)?o.s:(o[0]<<16)>>16}E 5u(r){F 1d.1W(1d.96*o.O/1d.95(r))}E 56(){D(o.s<0)F-1;J D(o.t<=0||(o.t==1&&o[0]<=0))F 0;J F 1}E 5s(b){D(b==Y)b=10;D(o.1G()==0||b<2||b>36)F"0";C 2J=o.3y(b);C a=1d.2y(b,2J);C d=1I(a),y=Q(),z=Q(),r="";o.1K(d,y,z);L(y.1G()>0){r=(a+z.3v()).1u(b).94(1)+r;y.1K(d,y,z)}F z.3v().1u(b)+r}E 5q(s,b){o.2d(0);D(b==Y)b=10;C 2J=o.3y(b);C d=1d.2y(b,2J),1X=1s,j=0,w=0;P(C i=0;i<s.Z;++i){C x=3K(s,i);D(x<0){D(s.2K(i)=="-"&&o.1G()==0)1X=1F;5L}w=b*w+x;D(++j>=2J){o.3w(d);o.2b(w,0);j=0;w=0}}D(j>0){o.3w(1d.2y(b,j));o.2b(w,0)}D(1X)G.1w.V(o,o)}E 5p(a,b,c){D("5K"==3J b){D(a<2)o.2d(1);J{o.3x(a,c);D(!o.4P(a-1))o.1S(G.1v.2Y(a-1),33,o);D(o.1j())o.2b(1,0);L(!o.4z(b)){o.2b(2,0);D(o.3B()>a)o.V(G.1v.2Y(a-1),o)}}}J{C x=U 1x(),t=a&7;x.Z=(a>>3)+1;b.5J(x);D(t>0)x[0]&=((1<<t)-1);J x[0]=0;o.35(x,1P)}}E 55(){C i=o.t,r=U 1x();r[0]=o.s;C p=o.O-(i*o.O)%8,d,k=0;D(i-->0){D(p<o.O&&(d=o[i]>>p)!=(o.s&o.1g)>>p)r[k++]=d|(o.s<<(o.O-p));L(i>=0){D(p<8){d=(o[i]&((1<<p)-1))<<(8-p);d|=o[--i]>>(p+=o.O-8)}J{d=(o[i]>>(p-=8))&2H;D(p<=0){p+=o.O;--i}}D((d&2I)!=0)d|=-1P;D(k==0&&(o.s&2I)!=(d&2I))++k;D(k>0||d!=o.s)r[k++]=d}}F r}E 54(a){F(o.1c(a)==0)}E 51(a){F(o.1c(a)<0)?o:a}E 50(a){F(o.1c(a)>0)?o:a}E 5o(a,1V,r){C i,f,m=1d.2a(a.t,o.t);P(i=0;i<m;++i)r[i]=1V(o[i],a[i]);D(a.t<o.t){f=a.s&o.1g;P(i=m;i<o.t;++i)r[i]=1V(o[i],f);r.t=o.t}J{f=o.s&o.1g;P(i=m;i<a.t;++i)r[i]=1V(f,a[i]);r.t=a.t}r.s=1V(o.s,a.s);r.1l()}E 5I(x,y){F x&y}E 4Z(a){C r=Q();o.1S(a,5I,r);F r}E 33(x,y){F x|y}E 4Y(a){C r=Q();o.1S(a,33,r);F r}E 3G(x,y){F x^y}E 4X(a){C r=Q();o.1S(a,3G,r);F r}E 3H(x,y){F x&~y}E 4W(a){C r=Q();o.1S(a,3H,r);F r}E 4V(){C r=Q();P(C i=0;i<o.t;++i)r[i]=o.1g&~o[i];r.t=o.t;r.s=~o.s;F r}E 4U(n){C r=Q();D(n<0)o.1h(-n,r);J o.2e(n,r);F r}E 4S(n){C r=Q();D(n<0)o.2e(-n,r);J o.1h(n,r);F r}E 5H(x){D(x==0)F-1;C r=0;D((x&34)==0){x>>=16;r+=16}D((x&2H)==0){x>>=8;r+=8}D((x&3I)==0){x>>=4;r+=4}D((x&3)==0){x>>=2;r+=2}D((x&1)==0)++r;F r}E 4R(){P(C i=0;i<o.t;++i)D(o[i]!=0)F i*o.O+5H(o[i]);D(o.s<0)F o.t*o.O;F-1}E 5G(x){C r=0;L(x!=0){x&=x-1;++r}F r}E 4Q(){C r=0,x=o.s&o.1g;P(C i=0;i<o.t;++i)r+=5G(o[i]^x);F r}E 4O(n){C j=1d.1W(n/o.O);D(j>=o.t)F(o.s!=0);F((o[j]&(1<<(n%o.O)))!=0)}E 5n(n,1V){C r=G.1v.2Y(n);o.1S(r,1V,r);F r}E 4N(n){F o.2Z(n,33)}E 4M(n){F o.2Z(n,3H)}E 4L(n){F o.2Z(n,3G)}E 5m(a,r){C i=0,c=0,m=1d.2a(a.t,o.t);L(i<m){c+=o[i]+a[i];r[i++]=c&o.1g;c>>=o.O}D(a.t<o.t){c+=a.s;L(i<o.t){c+=o[i];r[i++]=c&o.1g;c>>=o.O}c+=o.s}J{c+=o.s;L(i<a.t){c+=a[i];r[i++]=c&o.1g;c>>=o.O}c+=a.s}r.s=(c<0)?-1:0;D(c>0)r[i++]=c;J D(c<-1)r[i++]=o.1k+c;r.t=i;r.1l()}E 4K(a){C r=Q();o.2A(a,r);F r}E 4J(a){C r=Q();o.V(a,r);F r}E 4I(a){C r=Q();o.2h(a,r);F r}E 4G(a){C r=Q();o.1K(a,r,Y);F r}E 4F(a){C r=Q();o.1K(a,Y,r);F r}E 4E(a){C q=Q(),r=Q();o.1K(a,q,r);F U 1x(q,r)}E 5l(n){o[o.t]=o.am(0,n-1,o,0,0,o.t);++o.t;o.1l()}E 5k(n,w){L(o.t<=w)o[o.t++]=0;o[w]+=n;L(o[w]>=o.1k){o[w]-=o.1k;D(++w>=o.t)o[o.t++]=0;++o[w]}}E 2j(){}E 3F(x){F x}E 5F(x,y,r){x.2h(y,r)}E 5E(x,r){x.2F(r)}2j.H.2g=3F;2j.H.2f=3F;2j.H.1T=5F;2j.H.1A=5E;E 4B(e){F o.3E(e,U 2j())}E 5i(a,n,r){C i=1d.2a(o.t+a.t,n);r.s=0;r.t=i;L(i>0)r[--i]=0;C j;P(j=r.t-o.t;i<j;++i)r[i+o.t]=o.am(0,a[i],r,i,0,o.t);P(j=1d.2a(a.t,n);i<j;++i)o.am(0,a[i],r,i,0,n-i);r.1l()}E 5g(a,n,r){--n;C i=r.t=o.t+a.t-n;r.s=0;L(--i>=0)r[i]=0;P(i=1d.3u(n-o.t,0);i<a.t;++i)r[o.t+i-n]=o.am(n-i,a[i],r,0,0,o.t+i-n);r.1l();r.2G(1,r)}E 1U(m){o.1b=Q();o.3C=Q();G.1v.2i(2*m.t,o.1b);o.5D=o.1b.4H(m);o.m=m}E 5C(x){D(x.s<0||x.t>2*o.m.t)F x.3D(o.m);J D(x.1c(o.m)<0)F x;J{C r=Q();x.1J(r);o.1y(r);F r}}E 5B(x){F x}E 5A(x){x.2G(o.m.t-1,o.1b);D(x.t>o.m.t+1){x.t=o.m.t+1;x.1l()}o.5D.5h(o.1b,o.m.t+1,o.3C);o.m.5j(o.3C,o.m.t+1,o.1b);L(x.1c(o.1b)<0)x.2b(1,o.m.t+1);x.V(o.1b,x);L(x.1c(o.m)>=0)x.V(o.m,x)}E 5y(x,r){x.2F(r);o.1y(r)}E 5z(x,y,r){x.2h(y,r);o.1y(r)}1U.H.2g=5C;1U.H.2f=5B;1U.H.1y=5A;1U.H.1T=5z;1U.H.1A=5y;E 4D(e,m){C i=e.3B(),k,r=1I(1),z;D(i<=0)F r;J D(i<18)k=1;J D(i<48)k=3;J D(i<93)k=4;J D(i<92)k=5;J k=6;D(i<8)z=U 1O(m);J D(m.1j())z=U 1U(m);J z=U 1N(m);C g=U 1x(),n=3,2C=k-1,2D=(1<<k)-1;g[1]=z.2g(o);D(k>1){C 3A=Q();z.1A(g[1],3A);L(n<=2D){g[n]=Q();z.1T(3A,g[n-2],g[n]);n+=2}}C j=e.t-1,w,3z=1F,1b=Q(),t;i=2E(e[j])-1;L(j>=0){D(i>=2C)w=(e[j]>>(i-2C))&2D;J{w=(e[j]&((1<<(i+1))-1))<<(2C-i);D(j>0)w|=e[j-1]>>(o.O+i-2C)}n=k;L((w&1)==0){w>>=1;--n}D((i-=n)<0){i+=o.O;--j}D(3z){g[w].1J(r);3z=1s}J{L(n>1){z.1A(r,1b);z.1A(1b,r);n-=2}D(n>0)z.1A(r,1b);J{t=r;r=1b;1b=t}z.1T(1b,g[w],r)}L(j>=0&&(e[j]&(1<<i))==0){z.1A(r,1b);t=r;r=1b;1b=t;D(--i<0){i=o.O-1;--j}}}F z.2f(r)}E 4A(a){C x=(o.s<0)?o.2B():o.2z();C y=(a.s<0)?a.2B():a.2z();D(x.1c(y)<0){C t=x;x=y;y=t}C i=x.27(),g=y.27();D(g<0)F x;D(i<g)g=i;D(g>0){x.1h(g,x);y.1h(g,y)}L(x.1G()>0){D((i=x.27())>0)x.1h(i,x);D((i=y.27())>0)y.1h(i,y);D(x.1c(y)>=0){x.V(y,x);x.1h(1,x)}J{y.V(x,y);y.1h(1,y)}}D(g>0)y.2e(g,y);F y}E 5e(n){D(n<=0)F 0;C d=o.1k%n,r=(o.s<0)?n-1:0;D(o.t>0)D(d==0)r=o[0]%n;J P(C i=o.t-1;i>=0;--i)r=(d*r+o[i])%n;F r}E 4C(m){C ac=m.1j();D((o.1j()&&ac)||m.1G()==0)F G.1w;C u=m.2z(),v=o.2z();C a=1I(1),b=1I(0),c=1I(0),d=1I(1);L(u.1G()!=0){L(u.1j()){u.1h(1,u);D(ac){D(!a.1j()||!b.1j()){a.2A(o,a);b.V(m,b)}a.1h(1,a)}J D(!b.1j())b.V(m,b);b.1h(1,b)}L(v.1j()){v.1h(1,v);D(ac){D(!c.1j()||!d.1j()){c.2A(o,c);d.V(m,d)}c.1h(1,c)}J D(!d.1j())d.V(m,d);d.1h(1,d)}D(u.1c(v)>=0){u.V(v,u);D(ac)a.V(c,a);b.V(d,b)}J{v.V(u,v);D(ac)c.V(a,c);d.V(b,d)}}D(v.1c(G.1v)!=0)F G.1w;D(d.1c(m)>=0)F d.2V(m);D(d.1G()<0)d.2A(m,d);J F d;D(d.1G()<0)F d.3k(m);J F d}C 1i=[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,91,90,8Z,8Y,8X,5x,8W,8V,8U,8T,8S,8R,8Q,8P,8O,8N,8M,8L,8K,8J,8I,8H,8G,8F,8E,8D,8C,8B,8A,8z,8y,8x,8w,8v,8u,8t,8s,8r,8q,8p,8o,8n,8m,8l,8k,8j,8i,8h,8g,8f,8e,8d,8c,8b,8a,88,87,86,85,84,82,81,80,7Z,7Y,7X,7W,7V,7U,7T,7S,7R];C 5w=(1<<26)/1i[1i.Z-1];E 4y(t){C i,x=o.1H();D(x.t==1&&x[0]<=1i[1i.Z-1]){P(i=0;i<1i.Z;++i)D(x[0]==1i[i])F 1F;F 1s}D(x.1j())F 1s;i=1;L(i<1i.Z){C m=1i[i],j=i+1;L(j<1i.Z&&m<5w)m*=1i[j++];m=x.5f(m);L(i<j)D(m%1i[i++]==0)F 1s}F x.5d(t)}E 5c(t){C 2c=o.2V(G.1v);C k=2c.27();D(k<=0)F 1s;C r=2c.4T(k);t=(t+1)>>1;D(t>1i.Z)t=1i.Z;C a=Q();P(C i=0;i<t;++i){a.2d(1i[i]);C y=a.21(r,o);D(y.1c(G.1v)!=0&&y.1c(2c)!=0){C j=1;L(j++<k&&y.1c(2c)!=0){y=y.5v(2,o);D(y.1c(G.1v)==0)F 1s}D(y.1c(2c)!=0)F 1s}}F 1F}G.H.3y=5u;G.H.5t=5s;G.H.5r=5q;G.H.3x=5p;G.H.1S=5o;G.H.2Z=5n;G.H.2A=5m;G.H.3w=5l;G.H.2b=5k;G.H.5j=5i;G.H.5h=5g;G.H.5f=5e;G.H.5d=5c;G.H.2z=5b;G.H.3v=5a;G.H.7Q=58;G.H.7P=57;G.H.1G=56;G.H.7O=55;G.H.7N=54;G.H.2a=51;G.H.3u=50;G.H.7M=4Z;G.H.7L=4Y;G.H.7K=4X;G.H.7J=4W;G.H.2Q=4V;G.H.2Y=4U;G.H.4T=4S;G.H.27=4R;G.H.7I=4Q;G.H.4P=4O;G.H.7H=4N;G.H.7G=4M;G.H.7F=4L;G.H.3k=4K;G.H.2V=4J;G.H.3j=4I;G.H.4H=4G;G.H.7E=4F;G.H.7D=4E;G.H.21=4D;G.H.7C=4C;G.H.2y=4B;G.H.7B=4A;G.H.4z=4y;E 7A(4v,4u,4s,4t){C 4x="7z";C N=U G(4x,16);C g=U G("2");C k=U G("7y",16);C 4w=U 3t();C a=U G(32,4w);C A=g.21(a,N);C 3m=A.1u(16);C B=Y;C 3l=Y;C I=4v;C u=Y;C p=4u;C x=Y;C S=Y;C K=Y;C M=Y;C 3i=Y;C T=Y;C 2x=4t;C 4r=4s;C 1z=o;C 2P=1s;E 2w(1M){D(4r=="7x"){F 1M}};E 2v(4m,1t,4n){D(!T){D(2X.4q)T=U 4q();J D(2X.4p){7w{T=U 4p("4o.7v")}7u(e){}}J{1z.1R("4k 2Q 7t.");F}}D(T){T.7s=4n;T.7r("7q",4m,1F);T.3s("4l-7p","7o/x-7n-7m-7l");T.3s("4l-Z",1t.Z);T.3s("7k","7j");T.7i(1t)}J{1z.1R("4k 7h.")}};o.3q=E(){C 2W=2x+2w("3q/3r/");C 1t="I="+I;2v(2W,1t,4j)};E 4j(){D(T.2T==4&&T.2S==2R){D(T.1r.1q("3r").Z>0){C s=2u(T.1r.1q("3r")[0]);x=U G(1E(s+1E(I+":"+p)),16);C v=g.21(x,N);4i(v.1u(16))}J D(T.1r.1q("2t").Z>0){1z.1R(2u(T.1r.1q("2t")[0]))}}};E 4i(v){C 1t="v="+v;C 2U=2x+2w("3q/7g/");2v(2U,1t,4h)};E 4h(){D(T.2T==4&&T.2S==2R){D(T.1r.1q("7f").Z>0){1z.3o()}}};E 2u(4g){F 4g.7e.7d};o.3o=E(){C 2W=2x+2w("7c/");C 1t="I="+I+"&A="+3m;2v(2W,1t,4f)};E 4f(){D(T.2T==4&&T.2S==2R){D(T.1r.1q("r").Z>0){C 3p=T.1r.1q("r")[0];4d(3p.4e("s"),3p.4e("B"))}J D(T.1r.1q("2t").Z>0){1z.3o()}}};E 4d(s,3n){B=U G(3n,16);3l=3n;u=U G(1E(3m+3l),16);x=U G(1E(s+1E(I+":"+p)),16);C 4c=k.3j(g.21(x,N));C 4b=a.3k(u.3j(x));S=B.2V(4c).21(4b,N);C 4a=A.1u(16)+B.1u(16)+S.1u(16);M=1E(4a);49(M);3i=1E(A.1u(16)+M+S.1u(16))};E 49(M){C 1t="M="+M;C 2U=2x+2w("7b/");2v(2U,1t,46)};E 46(){D(T.2T==4&&T.2S==2R){D(T.1r.1q("M").Z>0){D(2u(T.1r.1q("M")[0])==3i){1z.45();2P=1F}J 1z.1R("7a 2s 78 2Q 77")}J D(T.1r.1q("2t").Z>0){1z.1R(2u(T.1r.1q("2t")[0]))}}};o.2s=E(){D(K==Y)D(2P){K=1E(S);F K}J 1z.1R("76 75 2Q 74 2P.");J F K};o.45=E(){44("72 70.")};o.1R=E(t){44(t)}};',62,660,'||||||||||||||||||||||||this||||||||||||||var|if|function|return|BigInteger|prototype||else||while|||DB|for|nbi|||xhr|new|subTo|||null|length|||||||||||HASH|r2|compareTo|Math|safe_add|rng_pptr|DM|rShiftTo|lowprimes|isEven|DV|clamp|ds|sh|vv|rng_pool|getElementsByTagName|responseXML|false|params|toString|ONE|ZERO|Array|reduce|that|sqrTo|ys|bs|255|SHA256|true|signum|abs|nbv|copyTo|divRemTo|dbits|str|Montgomery|Classic|256|utftext|error_message|bitwiseTo|mulTo|Barrett|op|floor|mi|pm|charCodeAt|rr|modPow||||||getLowestSetBit|||min|dAddOffset|n1|fromInt|lShiftTo|revert|convert|multiplyTo|dlShiftTo|NullExp|nsh|cbs|xh|xl|string|chrsz|fromCharCode|String|key|error|innerxml|ajaxRequest|paths|url|pow|clone|addTo|negate|k1|km|nbits|squareTo|drShiftTo|0xff|0x80|cs|charAt|0x7fff|bm|BI_RC|rng_state|authenticated|not|200|status|readyState|auth_url|subtract|handshake_url|window|shiftLeft|changeBit||||op_or|0xffff|fromString|||qd|y0|pt|BI_FP|navigator|rng_psize|Arcfour|binarray|128|T1|M2|multiply|add|Bstr|Astr|ephemeral|identify|response|register|salt|setRequestHeader|SecureRandom|max|intValue|dMultiply|fromNumber|chunkSize|is1|g2|bitLength|q3|mod|exp|nNop|op_xor|op_andnot|0xf|typeof|intAt|mpl|mp|ts|F2|yt|F1|int2char|appName|j_lm|0x3fff|ba|rng_seed_time|hex_tab|bin|T2|0xFFFF||lsw||alert|success|confirm_authentication|||send_hash|Mstr|aux|kgx|calculations|getAttribute|receive_salts|node|register_user|register_send_verifier|register_receive_salt|Ajax|Content|full_url|callback|Microsoft|ActiveXObject|XMLHttpRequest|server|ser|base_url|password|username|rng|Nstr|bnIsProbablePrime|isProbablePrime|bnGCD|bnPow|bnModInverse|bnModPow|bnDivideAndRemainder|bnRemainder|bnDivide|divide|bnMultiply|bnSubtract|bnAdd|bnFlipBit|bnClearBit|bnSetBit|bnTestBit|testBit|bnBitCount|bnGetLowestSetBit|bnShiftRight|shiftRight|bnShiftLeft|bnNot|bnAndNot|bnXor|bnOr|bnAnd|bnMax|bnMin|||bnEquals|bnToByteArray|bnSigNum|bnShortValue|bnByteValue||bnIntValue|bnClone|bnpMillerRabin|millerRabin|bnpModInt|modInt|bnpMultiplyUpperTo|multiplyUpperTo|bnpMultiplyLowerTo|multiplyLowerTo|bnpDAddOffset|bnpDMultiply|bnpAddTo|bnpChangeBit|bnpBitwiseTo|bnpFromNumber|bnpFromRadix|fromRadix|bnpToRadix|toRadix|bnpChunkSize|modPowInt|lplim|127|barrettSqrTo|barrettMulTo|barrettReduce|barrettRevert|barrettConvert|mu|nSqrTo|nMulTo|cbit|lbit|op_and|nextBytes|number|continue|bnModPowInt|bnMod|bnBitLength|bnCompareTo|bnAbs|bnNegate|bnToString|bnpExp|bnpIsEven|bnpInvDigit|invDigit|bnpDivRemTo|bnpSquareTo|bnpMultiplyTo|bnpSubTo||bnpRShiftTo|||bnpLShiftTo|bnpDRShiftTo||bnpDLShiftTo|bnpClamp|bnpFromString|bnpFromInt|bnpCopyTo|montSqrTo|montMulTo|montReduce|montRevert|montConvert|u0|um|mph|mt2|cSqrTo|cMulTo|cReduce|cRevert|cConvert|ms|d2|d1|FV|BI_RM|am3|am1|Netscape|am2|0x3fffffff|canary|rng_get_bytes|rng_get_byte|next|init|prng_newstate|random|crypto|rng_seed_int|ARC4next|ARC4init|str2binb|core_sha256|binb2hex|Utf8Encode|0xF|hexcase|mask|Maj|Sigma0256|Ch|Sigma1256|Gamma0256|Gamma1256|msw|successful||Authentication||been|has|User|match|does||Server|authenticate|handshake|nodeValue|firstChild|ok|user|failed|send|close|Connection|urlencoded|form|www|application|type|POST|open|onreadystatechange|supported|catch|XMLHTTP|try|django|c46d46600d87fef149bd79b81119842f3c20241fda67d06ef412d8f6d9479c58|115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3|SRP|gcd|modInverse|divideAndRemainder|remainder|flipBit|clearBit|setBit|bitCount|andNot|xor|or|and|equals|toByteArray|shortValue|byteValue|509|503|499|491|487|479|467|463|461|457|449|443||439|433|431|421|419||409|401|397|389|383|379|373|367|359|353|349|347|337|331|317|313|311|307|293|283|281|277|271|269|263|257|251|241|239|233|229|227|223|211|199|197|193|191|181|179|173|167|163|157|151|149|139|137|131|113|109|107|103|101|768|144|substr|log|LN2||0xffffffff|0123456789abcdefghijklmnopqrstuvwxyz|Explorer|Internet|0xfffffff|0x3ffffff|0x4000000|0xefcafe|0xffffff|0xdeadbeefcafe|65536|appVersion|getTime|Date|0123456789abcdef|0123456789ABCDEF|224|192|2048|replace|0x5BE0CD19|0x1F83D9AB|0x9B05688C|0x510E527F|0xA54FF53A|0x3C6EF372|0xBB67AE85|0x6A09E667|0xC67178F2|0xBEF9A3F7|0xA4506CEB|0x90BEFFFA|0x8CC70208|0x84C87814|0x78A5636F|0x748F82EE|0x682E6FF3|0x5B9CCA4F|0x4ED8AA4A|0x391C0CB3|0x34B0BCB5|0x2748774C|0x1E376C08|0x19A4C116|0x106AA070|0xF40E3585|0xD6990624|0xD192E819|0xC76C51A3|0xC24B8B70|0xA81A664B|0xA2BFE8A1|0x92722C85|0x81C2C92E|0x766A0ABB|0x650A7354|0x53380D13|0x4D2C6DFC|0x2E1B2138|0x27B70A85|0x14292967|0x6CA6351|0xD5A79147|0xC6E00BF3|0xBF597FC7|0xB00327C8||0xA831C66D|0x983E5152|0x76F988DA|0x5CB0A9DC|0x4A7484AA|0x2DE92C6F|0x240CA1CC|0xFC19DC6|0xEFBE4786||0xE49B69C1|0xC19BF174|0x9BDC06A7|0x80DEB1FE|0x72BE5D74|0x550C7DC3|0x243185BE|0x12835B01|0xD807AA98|0xAB1C5ED5|0x923F82A4|0x59F111F1|0x3956C25B|0xE9B5DBA5|0xB5C0FBCF|0x71374491|0x428A2F98'.split('|'),0,{}))
diff --git a/javascript/srp.js b/javascript/srp.js
index 0eff0ad..8a97e1d 100644
--- a/javascript/srp.js
+++ b/javascript/srp.js
@@ -32,7 +32,7 @@ function SRP(username, password, ser, base_url)
{
return str;
}
- }
+ };
function ajaxRequest(full_url, params, callback)
{
if(!xhr)
@@ -63,7 +63,7 @@ function SRP(username, password, ser, base_url)
{
that.error_message("Ajax failed.");
}
- }
+ };
this.register = function()
{
@@ -186,7 +186,7 @@ function SRP(username, password, ser, base_url)
that.error_message("User has not been authenticated.");
else
return K;
- }
+ };
this.success = function()
{
alert("Authentication successful.");