# Build encryption function
# We could, of course, leave f, g, and h as actual subroutine calls
# in the perl code, but it's a bit faster when everything is expanded
# inline.

use strict;
use warnings;

$_ = <<'END';
  f($l, $r, $k->[0],  $k->[16]);:
  g($r, $l, $k->[1],  $k->[17]);:
  h($l, $r, $k->[2],  $k->[18]);:
  f($r, $l, $k->[3],  $k->[19]);:
  g($l, $r, $k->[4],  $k->[20]);:
  h($r, $l, $k->[5],  $k->[21]);:
  f($l, $r, $k->[6],  $k->[22]);:
  g($r, $l, $k->[7],  $k->[23]);:
  h($l, $r, $k->[8],  $k->[24]);:
  f($r, $l, $k->[9],  $k->[25]);:
  g($l, $r, $k->[10], $k->[26]);:
  h($r, $l, $k->[11], $k->[27]);:
  if_($cast5->{rounds}_==_16)_{:
  __f($l, $r, $k->[12], $k->[28]);:
  __g($r, $l, $k->[13], $k->[29]);:
  __h($l, $r, $k->[14], $k->[30]);:
  __f($r, $l, $k->[15], $k->[31]);:
  }:
END

s{f\( ([^,]*),\s* ([^,]*),\s* ([^,]*),\s* ([^)]*) \)}
 { \$i = $3 + $2;
   ROT($4)
   $1 ^= ((\$s1[\$i>>24&255] ^ \$s2[\$i>>16&255])
         - \$s3[\$i>>8&255]) + \$s4[\$i&255]
 }gx;

s{g\( ([^,]*),\s* ([^,]*),\s* ([^,]*),\s* ([^)]*) \)}
 { \$i = $3 ^ $2;
   ROT($4)
   $1 ^= ((\$s1[\$i>>24&255] - \$s2[\$i>>16&255])
         + \$s3[\$i>>8&255]) ^ \$s4[\$i&255]
 }gx;

s{h\( ([^,]*),\s* ([^,]*),\s* ([^,]*),\s* ([^)]*) \)}
 { \$i = $3 - $2;
   ROT($4)
   $1 ^= ((\$s1[\$i>>24&255] + \$s2[\$i>>16&255])
         ^ \$s3[\$i>>8&255]) - \$s4[\$i&255]
 }gx;

s{ROT\( ([^)]*) \)}
 { \$j = $1;
   { no_integer;
     \$i = (\$i << \$j) | ((\$i & 0xffffffff) >> (32 - \$j))
   }
 }gx;

s/\s//g;
s/:/\n/g;
s/_/ /g;

print;

