From libdes 4.01

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1924 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Björn Groenvall
1997-06-22 10:23:25 +00:00
parent 571117c0ef
commit da0f8353ac
13 changed files with 7591 additions and 0 deletions

308
lib/des/asm/des-som2.pl Normal file
View File

@@ -0,0 +1,308 @@
#!/usr/local/bin/perl
#
# The inner loop instruction sequence and the IP/FP modifications are from
# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
#
$prog="des-som2.pl";
# base code is in microsft
# op dest, source
# format.
#
require "desboth.pl";
if ( ($ARGV[0] eq "elf"))
{ require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "a.out"))
{ $aout=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "sol"))
{ $sol=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "cpp"))
{ $cpp=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "win32"))
{ require "x86ms.pl"; }
else
{
print STDERR <<"EOF";
Pick one target type from
elf - linux, FreeBSD etc
a.out - old linux
sol - x86 solaris
cpp - format so x86unix.cpp can be used
win32 - Windows 95/Windows NT
EOF
exit(1);
}
&comment("Don't even think of reading this code");
&comment("It was automatically generated by $prog");
&comment("Which is a perl program used to generate the x86 assember for");
&comment("any of elf, a.out, Win32, or Solaris");
&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
&comment("eric <eay\@mincom.oz.au>");
&comment("The inner loop instruction sequence and the IP/FP modifications");
&comment("are from Svend Olaf Mikkelsen <svolaf\@inet.uni-c.dk>");
&comment("");
&file("dx86xxxx");
$L="edi";
$R="esi";
&des_encrypt("des_encrypt",1);
&des_encrypt("des_encrypt2",0);
&des_encrypt3("des_encrypt3",1);
&des_encrypt3("des_decrypt3",0);
&file_end();
sub des_encrypt
{
local($name,$do_ip)=@_;
&function_begin($name,3);
&comment("");
&comment("Load the 2 words");
&mov("eax",&wparam(0));
&mov($R,&DWP(0,"eax","",0));
&mov($L,&DWP(4,"eax","",0));
if ($do_ip)
{
&comment("");
&comment("IP");
&IP_new($R,$L,"eax",3);
# &comment("");
# &comment("fixup rotate");
# &rotl($R,3);
# &rotl($L,3);
}
else
{
&comment("");
&comment("fixup rotate");
&rotl($R,3);
&rotl($L,3);
}
&comment("");
&comment("load counter, key_schedule and enc flag");
# encrypting part
$ks="ebp";
# &xor( "ebx", "ebx" );
&mov("eax",&wparam(2)); # get encrypt flag
&xor( "ecx", "ecx" );
&cmp("eax","0");
&mov( $ks, &wparam(1) );
&je(&label("start_decrypt"));
for ($i=0; $i<16; $i+=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&jmp(&label("end"));
&set_label("start_decrypt");
for ($i=15; $i>0; $i-=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i-1));
&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&set_label("end");
if ($do_ip)
{
# &comment("");
# &comment("Fixup");
# &rotr($L,3); # r
# &rotr($R,3); # l
&comment("");
&comment("FP");
&FP_new($R,$L,"eax",3);
}
else
{
&comment("");
&comment("Fixup");
&rotr($L,3); # r
&rotr($R,3); # l
}
&mov("eax",&wparam(0));
&mov(&DWP(0,"eax","",0),$L);
&mov(&DWP(4,"eax","",0),$R);
&function_end($name);
}
sub D_ENCRYPT
{
local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
&mov( $u, &DWP(&n2a($S*4),$ks,"",0));
&xor( $tmp1, $tmp1);
&mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
&xor( $u, $R);
&xor( $t, $R);
&and( $u, "0xfcfcfcfc" );
&and( $t, "0xcfcfcfcf" );
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&rotr( $t, 4 );
&mov( $ks, &DWP(" $desSP",$tmp1,"",0));
&movb( &LB($tmp1), &LB($t) );
&xor( $L, $ks);
&mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp2), &HB($t) );
&shr( $u, 16);
&mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp1), &HB($u) );
&shr( $t, 16);
&mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
&xor( $L, $ks);
&mov( $ks, &DWP(24,"esp","",0)); ####
&movb( &LB($tmp2), &HB($t) );
&and( $u, "0xff" );
&and( $t, "0xff" );
&mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
&xor( $L, $tmp1);
}
sub PERM_OP
{
local($a,$b,$tt,$shift,$mask)=@_;
&mov( $tt, $a );
&shr( $tt, $shift );
&xor( $tt, $b );
&and( $tt, $mask );
&xor( $b, $tt );
&shl( $tt, $shift );
&xor( $a, $tt );
}
sub IP
{
local($l,$r,$tt)=@_;
&PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
&PERM_OP($l,$r,$tt,16,"0x0000ffff");
&PERM_OP($r,$l,$tt, 2,"0x33333333");
&PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
&PERM_OP($r,$l,$tt, 1,"0x55555555");
}
sub FP
{
local($l,$r,$tt)=@_;
&PERM_OP($l,$r,$tt, 1,"0x55555555");
&PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
&PERM_OP($l,$r,$tt, 2,"0x33333333");
&PERM_OP($r,$l,$tt,16,"0x0000ffff");
&PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
}
sub n2a
{
sprintf("%d",$_[0]);
}
# now has a side affect of rotating $a by $shift
sub R_PERM_OP
{
local($a,$b,$tt,$shift,$mask,$last)=@_;
&rotl( $a, $shift ) if ($shift != 0);
&mov( $tt, $b );
&xor( $tt, $a );
&and( $tt, $mask );
if ($last eq $b)
{
&xor( $a, $tt );
&xor( $b, $tt );
}
else
{
&xor( $b, $tt );
&xor( $a, $tt );
}
&comment("");
}
sub IP_new
{
local($l,$r,$tt,$lr)=@_;
&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
&R_PERM_OP($r,$l,$tt,20,"0xfff0000f",$l);
&R_PERM_OP($r,$l,$tt,14,"0x33333333",$r);
&R_PERM_OP($l,$r,$tt,22,"0x03fc03fc",$r);
&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
if ($lr != 3)
{
if (($lr-3) < 0)
{ &rotr($l, 3-$lr); }
else { &rotl($l, $lr-3); }
}
if ($lr != 2)
{
if (($lr-2) < 0)
{ &rotr($r, 2-$lr); }
else { &rotl($r, $lr-2); }
}
}
sub FP_new
{
local($r,$l,$tt,$lr)=@_;
if ($lr != 2)
{
if (($lr-2) < 0)
{ &rotl($r, 2-$lr); }
else { &rotr($r, $lr-2); }
}
if ($lr != 3)
{
if (($lr-3) < 0)
{ &rotl($l, 3-$lr); }
else { &rotr($l, $lr-3); }
}
&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
&R_PERM_OP($l,$r,$tt,23,"0x03fc03fc",$r);
&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
&R_PERM_OP($r,$l,$tt,18,"0xfff0000f",$l);
&R_PERM_OP($r,$l,$tt,12,"0xf0f0f0f0",$r);
&rotr($l , 4);
}

266
lib/des/asm/des-som3.pl Normal file
View File

@@ -0,0 +1,266 @@
#!/usr/local/bin/perl
#
# The inner loop instruction sequence and the IP/FP modifications are from
# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
#
$prog="des-som3.pl";
# base code is in microsft
# op dest, source
# format.
#
require "desboth.pl";
if ( ($ARGV[0] eq "elf"))
{ require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "a.out"))
{ $aout=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "sol"))
{ $sol=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "cpp"))
{ $cpp=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "win32"))
{ require "x86ms.pl"; }
else
{
print STDERR <<"EOF";
Pick one target type from
elf - linux, FreeBSD etc
a.out - old linux
sol - x86 solaris
cpp - format so x86unix.cpp can be used
win32 - Windows 95/Windows NT
EOF
exit(1);
}
&comment("Don't even think of reading this code");
&comment("It was automatically generated by $prog");
&comment("Which is a perl program used to generate the x86 assember for");
&comment("any of elf, a.out, Win32, or Solaris");
&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
&comment("eric <eay\@mincom.oz.au>");
&comment("The inner loop instruction sequence and the IP/FP modifications");
&comment("are from Svend Olaf Mikkelsen <svolaf\@inet.uni-c.dk>");
&comment("");
&file("dx86xxxx");
$L="edi";
$R="esi";
&des_encrypt("des_encrypt",1);
&des_encrypt("des_encrypt2",0);
&des_encrypt3("des_encrypt3",1);
&des_encrypt3("des_decrypt3",0);
&file_end();
sub des_encrypt
{
local($name,$do_ip)=@_;
&function_begin($name,3);
&comment("");
&comment("Load the 2 words");
$ks="ebp";
if ($do_ip)
{
&mov($R,&wparam(0));
&xor( "ecx", "ecx" );
&mov("eax",&DWP(0,$R,"",0));
&mov("ebx",&wparam(2)); # get encrypt flag
&mov($L,&DWP(4,$R,"",0));
&comment("");
&comment("IP");
&IP_new("eax",$L,$R,3);
}
else
{
&mov("eax",&wparam(0));
&xor( "ecx", "ecx" );
&mov($R,&DWP(0,"eax","",0));
&mov("ebx",&wparam(2)); # get encrypt flag
&rotl($R,3);
&mov($L,&DWP(4,"eax","",0));
&rotl($L,3);
}
&cmp("ebx","0");
&mov( $ks, &wparam(1) );
&je(&label("start_decrypt"));
for ($i=0; $i<16; $i+=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&jmp(&label("end"));
&set_label("start_decrypt");
for ($i=15; $i>0; $i-=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i-1));
&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&set_label("end");
if ($do_ip)
{
&comment("");
&comment("FP");
&mov("edx",&wparam(0));
&FP_new($L,$R,"eax",3);
&mov(&DWP(0,"edx","",0),"eax");
&mov(&DWP(4,"edx","",0),$R);
}
else
{
&comment("");
&comment("Fixup");
&rotr($L,3); # r
&mov("eax",&wparam(0));
&rotr($R,3); # l
&mov(&DWP(0,"eax","",0),$L);
&mov(&DWP(4,"eax","",0),$R);
}
&function_end($name);
}
sub D_ENCRYPT
{
local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
&mov( $u, &DWP(&n2a($S*4),$ks,"",0));
&xor( $tmp1, $tmp1);
&mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
&xor( $u, $R);
&xor( $t, $R);
&and( $u, "0xfcfcfcfc" );
&and( $t, "0xcfcfcfcf" );
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&rotr( $t, 4 );
&mov( $ks, &DWP(" $desSP",$tmp1,"",0));
&movb( &LB($tmp1), &LB($t) );
&xor( $L, $ks);
&mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp2), &HB($t) );
&shr( $u, 16);
&mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp1), &HB($u) );
&shr( $t, 16);
&mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
&xor( $L, $ks);
&mov( $ks, &DWP(24,"esp","",0)); ####
&movb( &LB($tmp2), &HB($t) );
&and( $u, "0xff" );
&and( $t, "0xff" );
&mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
&xor( $L, $tmp1);
}
sub n2a
{
sprintf("%d",$_[0]);
}
# now has a side affect of rotating $a by $shift
sub R_PERM_OP
{
local($a,$b,$tt,$shift,$mask,$last)=@_;
&rotl( $a, $shift ) if ($shift != 0);
&mov( $tt, $a );
&xor( $a, $b );
&and( $a, $mask );
if ($notlast eq $b)
{
&xor( $b, $a );
&xor( $tt, $a );
}
else
{
&xor( $tt, $a );
&xor( $b, $a );
}
&comment("");
}
sub IP_new
{
local($l,$r,$tt,$lr)=@_;
&R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
&R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
&R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
&R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
&R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
if ($lr != 3)
{
if (($lr-3) < 0)
{ &rotr($tt, 3-$lr); }
else { &rotl($tt, $lr-3); }
}
if ($lr != 2)
{
if (($lr-2) < 0)
{ &rotr($r, 2-$lr); }
else { &rotl($r, $lr-2); }
}
}
sub FP_new
{
local($l,$r,$tt,$lr)=@_;
if ($lr != 2)
{
if (($lr-2) < 0)
{ &rotl($r, 2-$lr); }
else { &rotr($r, $lr-2); }
}
if ($lr != 3)
{
if (($lr-3) < 0)
{ &rotl($l, 3-$lr); }
else { &rotr($l, $lr-3); }
}
&R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
&R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
&R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
&R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
&R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
&rotr($tt , 4);
}

210
lib/des/asm/des586.pl Normal file
View File

@@ -0,0 +1,210 @@
#!/usr/local/bin/perl
$prog="des586.pl";
# base code is in microsft
# op dest, source
# format.
#
# WILL NOT WORK ANYMORE WITH desboth.pl
require "desboth.pl";
if ( ($ARGV[0] eq "elf"))
{ require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "a.out"))
{ $aout=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "sol"))
{ $sol=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "cpp"))
{ $cpp=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "win32"))
{ require "x86ms.pl"; }
else
{
print STDERR <<"EOF";
Pick one target type from
elf - linux, FreeBSD etc
a.out - old linux
sol - x86 solaris
cpp - format so x86unix.cpp can be used
win32 - Windows 95/Windows NT
EOF
exit(1);
}
&comment("Don't even think of reading this code");
&comment("It was automatically generated by $prog");
&comment("Which is a perl program used to generate the x86 assember for");
&comment("any of elf, a.out, Win32, or Solaris");
&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
&comment("eric <eay\@mincom.oz.au>");
&comment("");
&file("dx86xxxx");
$L="edi";
$R="esi";
&des_encrypt("des_encrypt",1);
&des_encrypt("des_encrypt2",0);
&des_encrypt3("des_encrypt3",1);
&des_encrypt3("des_decrypt3",0);
&file_end();
sub des_encrypt
{
local($name,$do_ip)=@_;
&function_begin($name,3);
&comment("");
&comment("Load the 2 words");
&mov("eax",&wparam(0));
&mov($R,&DWP(0,"eax","",0));
&mov($L,&DWP(4,"eax","",0));
if ($do_ip)
{
&comment("");
&comment("IP");
&IP($R,$L,"eax");
}
&comment("");
&comment("fixup rotate");
&rotl($R,3);
&rotl($L,3);
&comment("");
&comment("load counter, key_schedule and enc flag");
# encrypting part
$ks="ebp";
&xor( "ebx", "ebx" );
&mov("eax",&wparam(2)); # get encrypt flag
&xor( "ecx", "ecx" );
&cmp("eax","0");
&mov( $ks, &wparam(1) );
&je(&label("start_decrypt"));
for ($i=0; $i<16; $i+=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&jmp(&label("end"));
&set_label("start_decrypt");
for ($i=15; $i>0; $i-=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i-1));
&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
}
&set_label("end");
&comment("");
&comment("Fixup");
&rotr($L,3); # r
&rotr($R,3); # l
if ($do_ip)
{
&comment("");
&comment("FP");
&FP($R,$L,"eax");
}
&mov("eax",&wparam(0));
&mov(&DWP(0,"eax","",0),$L);
&mov(&DWP(4,"eax","",0),$R);
&function_end($name);
}
sub D_ENCRYPT
{
local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
&mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
&mov( $u, &DWP(&n2a($S*4),$ks,"",0));
&xor( $t, $R);
&xor( $u, $R);
&rotr( $t, 4 );
&and( $u, "0xfcfcfcfc" );
&and( $t, "0xfcfcfcfc" );
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&xor( $L, &DWP(" $desSP",$tmp1,"",0));
&shr( $u, 16);
&xor( $L, &DWP("0x200+$desSP",$tmp2,"",0));
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&xor( $L, &DWP("0x400+$desSP",$tmp1,"",0));
&mov( $u, &DWP("0x600+$desSP",$tmp2,"",0));
&movb( &LB($tmp1), &LB($t) );
&movb( &LB($tmp2), &HB($t) );
&xor( $L, &DWP("0x100+$desSP",$tmp1,"",0));
&shr( $t, 16);
&xor( $u, &DWP("0x300+$desSP",$tmp2,"",0));
&movb( &LB($tmp1), &LB($t) );
&movb( &LB($tmp2), &HB($t) );
&xor( $L, &DWP("0x500+$desSP",$tmp1,"",0));
&xor( $u, &DWP("0x700+$desSP",$tmp2,"",0));
&xor( $L, $u);
}
sub PERM_OP
{
local($a,$b,$tt,$shift,$mask)=@_;
&mov( $tt, $a );
&shr( $tt, $shift );
&xor( $tt, $b );
&and( $tt, $mask );
&xor( $b, $tt );
&shl( $tt, $shift );
&xor( $a, $tt );
}
sub IP
{
local($l,$r,$tt)=@_;
&PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
&PERM_OP($l,$r,$tt,16,"0x0000ffff");
&PERM_OP($r,$l,$tt, 2,"0x33333333");
&PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
&PERM_OP($r,$l,$tt, 1,"0x55555555");
}
sub FP
{
local($l,$r,$tt)=@_;
&PERM_OP($l,$r,$tt, 1,"0x55555555");
&PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
&PERM_OP($l,$r,$tt, 2,"0x33333333");
&PERM_OP($r,$l,$tt,16,"0x0000ffff");
&PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
}
sub n2a
{
sprintf("%d",$_[0]);
}

230
lib/des/asm/des686.pl Normal file
View File

@@ -0,0 +1,230 @@
#!/usr/local/bin/perl
$prog="des686.pl";
# base code is in microsft
# op dest, source
# format.
#
# WILL NOT WORK ANYMORE WITH desboth.pl
require "desboth.pl";
if ( ($ARGV[0] eq "elf"))
{ require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "a.out"))
{ $aout=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "sol"))
{ $sol=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "cpp"))
{ $cpp=1; require "x86unix.pl"; }
elsif ( ($ARGV[0] eq "win32"))
{ require "x86ms.pl"; }
else
{
print STDERR <<"EOF";
Pick one target type from
elf - linux, FreeBSD etc
a.out - old linux
sol - x86 solaris
cpp - format so x86unix.cpp can be used
win32 - Windows 95/Windows NT
EOF
exit(1);
}
&comment("Don't even think of reading this code");
&comment("It was automatically generated by $prog");
&comment("Which is a perl program used to generate the x86 assember for");
&comment("any of elf, a.out, Win32, or Solaris");
&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
&comment("eric <eay\@mincom.oz.au>");
&comment("");
&file("dx86xxxx");
$L="edi";
$R="esi";
&des_encrypt("des_encrypt",1);
&des_encrypt("des_encrypt2",0);
&des_encrypt3("des_encrypt3",1);
&des_encrypt3("des_decrypt3",0);
&file_end();
sub des_encrypt
{
local($name,$do_ip)=@_;
&function_begin($name,3);
&comment("");
&comment("Load the 2 words");
&mov("eax",&wparam(0));
&mov($L,&DWP(0,"eax","",0));
&mov($R,&DWP(4,"eax","",0));
$ksp=&wparam(1);
if ($do_ip)
{
&comment("");
&comment("IP");
&IP($L,$R,"eax");
}
&comment("");
&comment("fixup rotate");
&rotl($R,3);
&rotl($L,3);
&exch($L,$R);
&comment("");
&comment("load counter, key_schedule and enc flag");
&mov("eax",&wparam(2)); # get encrypt flag
&mov("ebp",&wparam(1)); # get ks
&cmp("eax","0");
&je(&label("start_decrypt"));
# encrypting part
for ($i=0; $i<16; $i+=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
}
&jmp(&label("end"));
&set_label("start_decrypt");
for ($i=15; $i>0; $i-=2)
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
&comment("");
&comment("Round ".sprintf("%d",$i-1));
&D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
}
&set_label("end");
&comment("");
&comment("Fixup");
&rotr($L,3); # r
&rotr($R,3); # l
if ($do_ip)
{
&comment("");
&comment("FP");
&FP($R,$L,"eax");
}
&mov("eax",&wparam(0));
&mov(&DWP(0,"eax","",0),$L);
&mov(&DWP(4,"eax","",0),$R);
&function_end($name);
}
# The logic is to load R into 2 registers and operate on both at the same time.
# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
# while also masking the other copy and doing a lookup. We then also accumulate the
# L value in 2 registers then combine them at the end.
sub D_ENCRYPT
{
local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
&mov( $u, &DWP(&n2a($S*4),$ks,"",0));
&mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
&xor( $u, $R );
&xor( $t, $R );
&rotr( $t, 4 );
# the numbers at the end of the line are origional instruction order
&mov( $tmp2, $u ); # 1 2
&mov( $tmp1, $t ); # 1 1
&and( $tmp2, "0xfc" ); # 1 4
&and( $tmp1, "0xfc" ); # 1 3
&shr( $t, 8 ); # 1 5
&xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
&shr( $u, 8 ); # 1 6
&mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
&mov( $tmp2, $u ); # 2 2
&xor( $L, $tmp1 ); # 1 9
&and( $tmp2, "0xfc" ); # 2 4
&mov( $tmp1, $t ); # 2 1
&and( $tmp1, "0xfc" ); # 2 3
&shr( $t, 8 ); # 2 5
&xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
&shr( $u, 8 ); # 2 6
&mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
&mov( $tmp2, $u ); # 3 2
&xor( $L, $tmp1 ); # 2 9
&and( $tmp2, "0xfc" ); # 3 4
&mov( $tmp1, $t ); # 3 1
&shr( $u, 8 ); # 3 6
&and( $tmp1, "0xfc" ); # 3 3
&shr( $t, 8 ); # 3 5
&xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
&mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
&and( $t, "0xfc" ); # 4 1
&xor( $L, $tmp1 ); # 3 9
&and( $u, "0xfc" ); # 4 2
&xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
&xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
}
sub PERM_OP
{
local($a,$b,$tt,$shift,$mask)=@_;
&mov( $tt, $a );
&shr( $tt, $shift );
&xor( $tt, $b );
&and( $tt, $mask );
&xor( $b, $tt );
&shl( $tt, $shift );
&xor( $a, $tt );
}
sub IP
{
local($l,$r,$tt)=@_;
&PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
&PERM_OP($l,$r,$tt,16,"0x0000ffff");
&PERM_OP($r,$l,$tt, 2,"0x33333333");
&PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
&PERM_OP($r,$l,$tt, 1,"0x55555555");
}
sub FP
{
local($l,$r,$tt)=@_;
&PERM_OP($l,$r,$tt, 1,"0x55555555");
&PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
&PERM_OP($l,$r,$tt, 2,"0x33333333");
&PERM_OP($r,$l,$tt,16,"0x0000ffff");
&PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
}
sub n2a
{
sprintf("%d",$_[0]);
}

67
lib/des/asm/desboth.pl Normal file
View File

@@ -0,0 +1,67 @@
#!/usr/local/bin/perl
$L="edi";
$R="esi";
sub des_encrypt3
{
local($name,$enc)=@_;
&function_begin($name,4);
&comment("");
&comment("Load the data words");
&mov("ebx",&wparam(0));
&mov($L,&DWP(0,"ebx","",0));
&mov($R,&DWP(4,"ebx","",0));
&comment("");
&comment("IP");
&IP_new($L,$R,"edx",0);
# put them back
if ($enc)
{
&mov(&DWP(4,"ebx","",0),$R);
&mov("eax",&wparam(1));
&mov(&DWP(0,"ebx","",0),"edx");
&mov("edi",&wparam(2));
&mov("esi",&wparam(3));
}
else
{
&mov(&DWP(4,"ebx","",0),$R);
&mov("esi",&wparam(1));
&mov(&DWP(0,"ebx","",0),"edx");
&mov("edi",&wparam(2));
&mov("eax",&wparam(3));
}
&push(($enc)?"1":"0");
&push("eax");
&push("ebx");
&call("des_encrypt2");
&push(($enc)?"0":"1");
&push("edi");
&push("ebx");
&call("des_encrypt2");
&push(($enc)?"1":"0");
&push("esi");
&push("ebx");
&call("des_encrypt2");
&mov($L,&DWP(0,"ebx","",0));
&add("esp",36);
&mov($R,&DWP(4,"ebx","",0));
&comment("");
&comment("FP");
&FP_new($L,$R,"eax",0);
&mov(&DWP(0,"ebx","",0),"eax");
&mov(&DWP(4,"ebx","",0),$R);
&function_end($name);
}

2780
lib/des/asm/dx86-cpp.s Normal file

File diff suppressed because it is too large Load Diff

39
lib/des/asm/dx86unix.cpp Normal file
View File

@@ -0,0 +1,39 @@
#define TYPE(a,b) .type a,b
#define SIZE(a,b) .size a,b
#ifdef OUT
#define OK 1
#define des_SPtrans _des_SPtrans
#define des_encrypt _des_encrypt
#define des_encrypt2 _des_encrypt2
#define des_encrypt3 _des_encrypt3
#define ALIGN 4
#endif
#ifdef BSDI
#define OK 1
#define des_SPtrans _des_SPtrans
#define des_encrypt _des_encrypt
#define des_encrypt2 _des_encrypt2
#define des_encrypt3 _des_encrypt3
#define ALIGN 4
#undef SIZE
#undef TYPE
#endif
#if defined(ELF) || defined(SOL)
#define OK 1
#define ALIGN 16
#endif
#ifndef OK
You need to define one of
ELF - elf systems - linux-elf, NetBSD and DG-UX
OUT - a.out systems - linux-a.out and FreeBSD
SOL - solaris systems, which are elf with strange comment lines
BSDI - a.out with a very primative version of as.
#endif
#include "dx86-cpp.s"

130
lib/des/asm/readme Normal file
View File

@@ -0,0 +1,130 @@
First up, let me say I don't like writing in assembler. It is not portable,
dependant on the particular CPU architecture release and is generally a pig
to debug and get right. Having said that, the x86 architecture is probably
the most important for speed due to number of boxes and since
it appears to be the worst architecture to to get
good C compilers for. So due to this, I have lowered myself to do
assembler for the inner DES routines in libdes :-).
The file to implement in assembler is des_enc.c. Replace the following
4 functions
des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
They encrypt/decrypt the 64 bits held in 'data' using
the 'ks' key schedules. The only difference between the 4 functions is that
des_encrypt2() does not perform IP() or FP() on the data (this is an
optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
perform triple des. The triple DES routines are in here because it does
make a big difference to have them located near the des_encrypt2 function
at link time..
Now as we all know, there are lots of different operating systems running on
x86 boxes, and unfortunately they normally try to make sure their assembler
formating is not the same as the other peoples.
The 4 main formats I know of are
Microsoft Windows 95/Windows NT
Elf Includes Linux and FreeBSD(?).
a.out The older Linux.
Solaris Same as Elf but different comments :-(.
Now I was not overly keen to write 4 different copies of the same code,
so I wrote a few perl routines to output the correct assembler, given
a target assembler type. This code is ugly and is just a hack.
The libraries are x86unix.pl and x86ms.pl.
des586.pl, des686.pl and des-som[23].pl are the programs to actually
generate the assembler.
So to generate elf assembler
perl des-som3.pl elf >dx86-elf.s
For Windows 95/NT
perl des-som2.pl win32 >win32.asm
[ update 4 Jan 1996 ]
I have added another way to do things.
perl des-som3.pl cpp >dx86-cpp.s
generates a file that will be included by dx86unix.cpp when it is compiled.
To build for elf, a.out, solaris, bsdi etc,
cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
This was done to cut down the number of files in the distribution.
Now the ugly part. I acquired my copy of Intels
"Optimization's For Intel's 32-Bit Processors" and found a few interesting
things. First, the aim of the exersize is to 'extract' one byte at a time
from a word and do an array lookup. This involves getting the byte from
the 4 locations in the word and moving it to a new word and doing the lookup.
The most obvious way to do this is
xor eax, eax # clear word
movb al, cl # get low byte
xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
movb al, ch # get next byte
xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
shr ecx 16
which seems ok. For the pentium, this system appears to be the best.
One has to do instruction interleaving to keep both functional units
operating, but it is basically very efficient.
Now the crunch. When a full register is used after a partial write, eg.
mov al, cl
xor edi, DWORD PTR 0x100+des_SP[eax]
386 - 1 cycle stall
486 - 1 cycle stall
586 - 0 cycle stall
686 - at least 7 cycle stall (page 22 of the above mentioned document).
So the technique that produces the best results on a pentium, according to
the documentation, will produce hideous results on a pentium pro.
To get around this, des686.pl will generate code that is not as fast on
a pentium, should be very good on a pentium pro.
mov eax, ecx # copy word
shr ecx, 8 # line up next byte
and eax, 0fch # mask byte
xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
mov eax, ecx # get word
shr ecx 8 # line up next byte
and eax, 0fch # mask byte
xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
Due to the execution units in the pentium, this actually works quite well.
For a pentium pro it should be very good. This is the type of output
Visual C++ generates.
There is a third option. instead of using
mov al, ch
which is bad on the pentium pro, one may be able to use
movzx eax, ch
which may not incur the partial write penalty. On the pentium,
this instruction takes 4 cycles so is not worth using but on the
pentium pro it appears it may be worth while. I need access to one to
experiment :-).
eric (20 Oct 1996)
22 Nov 1996 - I have asked people to run the 2 different version on pentium
pros and it appears that the intel documentation is wrong. The
mov al,bh is still faster on a pentium pro, so just use the des586.pl
install des686.pl
3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
functions into des_enc.c because it does make a massive performance
difference on some boxes to have the functions code located close to
the des_encrypt2() function.
9 Jan 1996 - des-som2.pl is now the correct perl script to use for
pentiums. It contains an inner loop from
Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
273,000 per second. He had a previous version at 250,000 and the best
I was able to get was 203,000. The content has not changed, this is all
due to instruction sequencing (and actual instructions choice) which is able
to keep both functional units of the pentium going.
We may have lost the ugly register usage restrictions when x86 went 32 bit
but for the pentium it has been replaced by evil instruction ordering tricks.
13 Jan 1996 - des-som3.pl, more optimizations from Svend Olaf.
raw DES at 281,000 per second on a pentium 100.

2766
lib/des/asm/win32.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
lib/des/asm/win32.obj Normal file

Binary file not shown.

319
lib/des/asm/win32.uu Normal file
View File

@@ -0,0 +1,319 @@
begin 644 win32.obj
M3`$"`&*'V3)`-@``#``````````N=&5X=```````````````W"$``&0```!`
M(@`````````"```@`#!@+F1A=&$```#<(0````````````!`-@``````````
M````````0``PP%535E>+="04,\F+!HM<)!R+?@3!P`2+\#/')?#P\/`S\#/X
MP<<4B\<S_H'G#P#P_S/',_?!P`Z+^#/&)3,S,S,S^#/PP<86B\8S]X'F_`/\
M`S/&,_[!P`F+\#/'):JJJJHS\#/XT<>#^P"+;"08#X2U!P``BT4`,]N+500S
MQC/6)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS_8NI``(``#/]BL[!Z!"+
MJP`!```S_8K<P>H0BZD``P``,_V+;"08BLXE_P```('B_P```(N;``8``#/[
MBYD`!P``,_N+F``$```S^XN:``4``#/[BT4(,]N+50PSQS/7)?S\_/R!XL_/
MS\^*V(K,P<H$BZL`````BMHS]8NI``(``#/UBL[!Z!"+JP`!```S]8K<P>H0
MBZD``P``,_6+;"08BLXE_P```('B_P```(N;``8``#/SBYD`!P``,_.+F``$
M```S\XN:``4``#/SBT40,]N+510SQC/6)?S\_/R!XL_/S\^*V(K,P<H$BZL`
M````BMHS_8NI``(``#/]BL[!Z!"+JP`!```S_8K<P>H0BZD``P``,_V+;"08
MBLXE_P```('B_P```(N;``8``#/[BYD`!P``,_N+F``$```S^XN:``4``#/[
MBT48,]N+51PSQS/7)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS]8NI``(`
M`#/UBL[!Z!"+JP`!```S]8K<P>H0BZD``P``,_6+;"08BLXE_P```('B_P``
M`(N;``8``#/SBYD`!P``,_.+F``$```S\XN:``4``#/SBT4@,]N+520SQC/6
M)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS_8NI``(``#/]BL[!Z!"+JP`!
M```S_8K<P>H0BZD``P``,_V+;"08BLXE_P```('B_P```(N;``8``#/[BYD`
M!P``,_N+F``$```S^XN:``4``#/[BT4H,]N+52PSQS/7)?S\_/R!XL_/S\^*
MV(K,P<H$BZL`````BMHS]8NI``(``#/UBL[!Z!"+JP`!```S]8K<P>H0BZD`
M`P``,_6+;"08BLXE_P```('B_P```(N;``8``#/SBYD`!P``,_.+F``$```S
M\XN:``4``#/SBT4P,]N+530SQC/6)?S\_/R!XL_/S\^*V(K,P<H$BZL`````
MBMHS_8NI``(``#/]BL[!Z!"+JP`!```S_8K<P>H0BZD``P``,_V+;"08BLXE
M_P```('B_P```(N;``8``#/[BYD`!P``,_N+F``$```S^XN:``4``#/[BT4X
M,]N+53PSQS/7)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS]8NI``(``#/U
MBL[!Z!"+JP`!```S]8K<P>H0BZD``P``,_6+;"08BLXE_P```('B_P```(N;
M``8``#/SBYD`!P``,_.+F``$```S\XN:``4``#/SBT5`,]N+540SQC/6)?S\
M_/R!XL_/S\^*V(K,P<H$BZL`````BMHS_8NI``(``#/]BL[!Z!"+JP`!```S
M_8K<P>H0BZD``P``,_V+;"08BLXE_P```('B_P```(N;``8``#/[BYD`!P``
M,_N+F``$```S^XN:``4``#/[BT5(,]N+54PSQS/7)?S\_/R!XL_/S\^*V(K,
MP<H$BZL`````BMHS]8NI``(``#/UBL[!Z!"+JP`!```S]8K<P>H0BZD``P``
M,_6+;"08BLXE_P```('B_P```(N;``8``#/SBYD`!P``,_.+F``$```S\XN:
M``4``#/SBT50,]N+550SQC/6)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS
M_8NI``(``#/]BL[!Z!"+JP`!```S_8K<P>H0BZD``P``,_V+;"08BLXE_P``
M`('B_P```(N;``8``#/[BYD`!P``,_N+F``$```S^XN:``4``#/[BT58,]N+
M55PSQS/7)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS]8NI``(``#/UBL[!
MZ!"+JP`!```S]8K<P>H0BZD``P``,_6+;"08BLXE_P```('B_P```(N;``8`
M`#/SBYD`!P``,_.+F``$```S\XN:``4``#/SBT5@,]N+560SQC/6)?S\_/R!
MXL_/S\^*V(K,P<H$BZL`````BMHS_8NI``(``#/]BL[!Z!"+JP`!```S_8K<
MP>H0BZD``P``,_V+;"08BLXE_P```('B_P```(N;``8``#/[BYD`!P``,_N+
MF``$```S^XN:``4``#/[BT5H,]N+56PSQS/7)?S\_/R!XL_/S\^*V(K,P<H$
MBZL`````BMHS]8NI``(``#/UBL[!Z!"+JP`!```S]8K<P>H0BZD``P``,_6+
M;"08BLXE_P```('B_P```(N;``8``#/SBYD`!P``,_.+F``$```S\XN:``4`
M`#/SBT5P,]N+570SQC/6)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS_8NI
M``(``#/]BL[!Z!"+JP`!```S_8K<P>H0BZD``P``,_V+;"08BLXE_P```('B
M_P```(N;``8``#/[BYD`!P``,_N+F``$```S^XN:``4``#/[BT5X,]N+57PS
MQS/7)?S\_/R!XL_/S\^*V(K,P<H$BZL`````BMHS]8NI``(``#/UBL[!Z!"+
MJP`!```S]8K<P>H0BZD``P``,_6+;"08BLXE_P```('B_P```(N;``8``#/S
MBYD`!P``,_.+F``$```S\XN:``4``#/SZ;`'``"+17@SVXM5?#/&,]8E_/S\
M_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]
MBMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S
M^XN8``0``#/[BYH`!0``,_N+17`SVXM5=#/',]<E_/S\_('BS\_/SXK8BLS!
MR@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S
M]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`
M!0``,_.+16@SVXM5;#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]
MBZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````
M@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+16`SVXM5
M9#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H
M$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``
M,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+15@SVXM57#/&,]8E_/S\_('B
MS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!
MZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8
M``0``#/[BYH`!0``,_N+15`SVXM55#/',]<E_/S\_('BS\_/SXK8BLS!R@2+
MJP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML
M)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``
M,_.+14@SVXM53#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD`
M`@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_
M````BYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+14`SVXM51#/'
M,]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK
M``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+
MF0`'```S\XN8``0``#/SBYH`!0``,_.+13@SVXM5/#/&,]8E_/S\_('BS\_/
MSXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+
MJ0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0`
M`#/[BYH`!0``,_N+13`SVXM5-#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP``
M``"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*
MSB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+
M12@SVXM5+#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``
M,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````
MBYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+12`SVXM5)#/',]<E
M_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$`
M`#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'
M```S\XN8``0``#/SBYH`!0``,_.+11@SVXM5'#/&,]8E_/S\_('BS\_/SXK8
MBLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#
M```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[
MBYH`!0``,_N+11`SVXM5%#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*
MVC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_
M````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+10@S
MVXM5##/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*
MSL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`
M!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+10`SVXM5!#/',]<E_/S\
M_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/U
MBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S
M\XN8``0``#/SBYH`!0``,_.+5"04T<Z+QS/^@>>JJJJJ,\<S]\'`%XOX,\8E
M_`/\`S/X,_#!QPJ+QS/^@><S,S,S,\<S]\'&$HO^,_"!Y@\`\/\S_C/&P<<,
MB_<S^('G\/#P\#/W,\?!R`2)`HER!%]>6UW#55-65XM$)!0SR8LPBUPD','&
M`XMX!,''`X/[`(ML)!@/A+4'``"+10`SVXM5!#/&,]8E_/S\_('BS\_/SXK8
MBLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#
M```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[
MBYH`!0``,_N+10@SVXM5##/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*
MVC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_
M````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+11`S
MVXM5%#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*
MSL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`
M!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+11@SVXM5'#/',]<E_/S\
M_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/U
MBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S
M\XN8``0``#/SBYH`!0``,_.+12`SVXM5)#/&,]8E_/S\_('BS\_/SXK8BLS!
MR@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S
M_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`
M!0``,_N+12@SVXM5+#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/U
MBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````
M@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+13`SVXM5
M-#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H
M$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``
M,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+13@SVXM5/#/',]<E_/S\_('B
MS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!
MZA"+J0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8
M``0``#/SBYH`!0``,_.+14`SVXM51#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+
MJP````"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML
M)!B*SB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``
M,_N+14@SVXM53#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD`
M`@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_
M````BYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+15`SVXM55#/&
M,]8E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK
M``$``#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+
MF0`'```S^XN8``0``#/[BYH`!0``,_N+15@SVXM57#/',]<E_/S\_('BS\_/
MSXK8BLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+
MJ0`#```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8``0`
M`#/SBYH`!0``,_.+16`SVXM59#/&,]8E_/S\_('BS\_/SXK8BLS!R@2+JP``
M``"*VC/]BZD``@``,_V*SL'H$(NK``$``#/]BMS!ZA"+J0`#```S_8ML)!B*
MSB7_````@>+_````BYL`!@``,_N+F0`'```S^XN8``0``#/[BYH`!0``,_N+
M16@SVXM5;#/',]<E_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/UBZD``@``
M,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#```S]8ML)!B*SB7_````@>+_````
MBYL`!@``,_.+F0`'```S\XN8``0``#/SBYH`!0``,_.+17`SVXM5=#/&,]8E
M_/S\_('BS\_/SXK8BLS!R@2+JP````"*VC/]BZD``@``,_V*SL'H$(NK``$`
M`#/]BMS!ZA"+J0`#```S_8ML)!B*SB7_````@>+_````BYL`!@``,_N+F0`'
M```S^XN8``0``#/[BYH`!0``,_N+17@SVXM5?#/',]<E_/S\_('BS\_/SXK8
MBLS!R@2+JP````"*VC/UBZD``@``,_6*SL'H$(NK``$``#/UBMS!ZA"+J0`#
M```S]8ML)!B*SB7_````@>+_````BYL`!@``,_.+F0`'```S\XN8``0``#/S
MBYH`!0``,_/IL`<``(M%>#/;BU5\,\8SUB7\_/S\@>+/S\_/BMB*S,'*!(NK
M`````(K:,_V+J0`"```S_8K.P>@0BZL``0``,_V*W,'J$(NI``,``#/]BVPD
M&(K.)?\```"!XO\```"+FP`&```S^XN9``<``#/[BY@`!```,_N+F@`%```S
M^XM%<#/;BU5T,\<SUR7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_6+J0`"
M```S]8K.P>@0BZL``0``,_6*W,'J$(NI``,``#/UBVPD&(K.)?\```"!XO\`
M``"+FP`&```S\XN9``<``#/SBY@`!```,_.+F@`%```S\XM%:#/;BU5L,\8S
MUB7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_V+J0`"```S_8K.P>@0BZL`
M`0``,_V*W,'J$(NI``,``#/]BVPD&(K.)?\```"!XO\```"+FP`&```S^XN9
M``<``#/[BY@`!```,_N+F@`%```S^XM%8#/;BU5D,\<SUR7\_/S\@>+/S\_/
MBMB*S,'*!(NK`````(K:,_6+J0`"```S]8K.P>@0BZL``0``,_6*W,'J$(NI
M``,``#/UBVPD&(K.)?\```"!XO\```"+FP`&```S\XN9``<``#/SBY@`!```
M,_.+F@`%```S\XM%6#/;BU5<,\8SUB7\_/S\@>+/S\_/BMB*S,'*!(NK````
M`(K:,_V+J0`"```S_8K.P>@0BZL``0``,_V*W,'J$(NI``,``#/]BVPD&(K.
M)?\```"!XO\```"+FP`&```S^XN9``<``#/[BY@`!```,_N+F@`%```S^XM%
M4#/;BU54,\<SUR7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_6+J0`"```S
M]8K.P>@0BZL``0``,_6*W,'J$(NI``,``#/UBVPD&(K.)?\```"!XO\```"+
MFP`&```S\XN9``<``#/SBY@`!```,_.+F@`%```S\XM%2#/;BU5,,\8SUB7\
M_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_V+J0`"```S_8K.P>@0BZL``0``
M,_V*W,'J$(NI``,``#/]BVPD&(K.)?\```"!XO\```"+FP`&```S^XN9``<`
M`#/[BY@`!```,_N+F@`%```S^XM%0#/;BU5$,\<SUR7\_/S\@>+/S\_/BMB*
MS,'*!(NK`````(K:,_6+J0`"```S]8K.P>@0BZL``0``,_6*W,'J$(NI``,`
M`#/UBVPD&(K.)?\```"!XO\```"+FP`&```S\XN9``<``#/SBY@`!```,_.+
MF@`%```S\XM%.#/;BU4\,\8SUB7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:
M,_V+J0`"```S_8K.P>@0BZL``0``,_V*W,'J$(NI``,``#/]BVPD&(K.)?\`
M``"!XO\```"+FP`&```S^XN9``<``#/[BY@`!```,_N+F@`%```S^XM%,#/;
MBU4T,\<SUR7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_6+J0`"```S]8K.
MP>@0BZL``0``,_6*W,'J$(NI``,``#/UBVPD&(K.)?\```"!XO\```"+FP`&
M```S\XN9``<``#/SBY@`!```,_.+F@`%```S\XM%*#/;BU4L,\8SUB7\_/S\
M@>+/S\_/BMB*S,'*!(NK`````(K:,_V+J0`"```S_8K.P>@0BZL``0``,_V*
MW,'J$(NI``,``#/]BVPD&(K.)?\```"!XO\```"+FP`&```S^XN9``<``#/[
MBY@`!```,_N+F@`%```S^XM%(#/;BU4D,\<SUR7\_/S\@>+/S\_/BMB*S,'*
M!(NK`````(K:,_6+J0`"```S]8K.P>@0BZL``0``,_6*W,'J$(NI``,``#/U
MBVPD&(K.)?\```"!XO\```"+FP`&```S\XN9``<``#/SBY@`!```,_.+F@`%
M```S\XM%&#/;BU4<,\8SUB7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_V+
MJ0`"```S_8K.P>@0BZL``0``,_V*W,'J$(NI``,``#/]BVPD&(K.)?\```"!
MXO\```"+FP`&```S^XN9``<``#/[BY@`!```,_N+F@`%```S^XM%$#/;BU44
M,\<SUR7\_/S\@>+/S\_/BMB*S,'*!(NK`````(K:,_6+J0`"```S]8K.P>@0
MBZL``0``,_6*W,'J$(NI``,``#/UBVPD&(K.)?\```"!XO\```"+FP`&```S
M\XN9``<``#/SBY@`!```,_.+F@`%```S\XM%"#/;BU4,,\8SUB7\_/S\@>+/
MS\_/BMB*S,'*!(NK`````(K:,_V+J0`"```S_8K.P>@0BZL``0``,_V*W,'J
M$(NI``,``#/]BVPD&(K.)?\```"!XO\```"+FP`&```S^XN9``<``#/[BY@`
M!```,_N+F@`%```S^XM%`#/;BU4$,\<SUR7\_/S\@>+/S\_/BMB*S,'*!(NK
M`````(K:,_6+J0`"```S]8K.P>@0BZL``0``,_6*W,'J$(NI``,``#/UBVPD
M&(K.)?\```"!XO\```"+FP`&```S\XN9``<``#/SBY@`!```,_.+F@`%```S
M\\'/`XM$)!3!S@.).(EP!%]>6UW#55-65XM<)!2+.XMS!,''!(O7,_Z!Y_#P
M\/`SUS/WP<84B_XS\H'F#P#P_S/^,];!QPZ+]S/Z@><S,S,S,_<SU\'"%HOZ
M,]:!XOP#_`,S^C/RP<<)B]<S_H'GJJJJJC/7,_?!R@/!S@*)<P2+1"08B1.+
M?"0<BW0D(&H!4%/HW^___VH`5U/HUN___VH!5E/HS>___XL[@\0DBW,$P<8"
MP<<#B\<S_H'GJJJJJC/',_?!P!>+^#/&)?P#_`,S^#/PP<<*B\<S_H'G,S,S
M,S/',_?!QA*+_C/P@>8/`/#_,_XSQL''#(OW,_B!Y_#P\/`S]S/'P<@$B0.)
M<P1?7EM=PU535E>+7"04BSN+<P3!QP2+US/^@>?P\/#P,]<S]\'&%(O^,_*!
MY@\`\/\S_C/6P<<.B_<S^H'G,S,S,S/W,]?!PA:+^C/6@>+\`_P#,_HS\L''
M"8O7,_Z!YZJJJJHSUS/WP<H#P<X"B7,$BW0D&(D3BWPD'(M$)"!J`%!3Z-_N
M__]J`5=3Z-;N__]J`%93Z,WN__^+.X/$)(MS!,'&`L''`XO',_Z!YZJJJJHS
MQS/WP<`7B_@SQB7\`_P#,_@S\,''"HO',_Z!YS,S,S,SQS/WP<82B_XS\('F
M#P#P_S/^,\;!QPR+]S/X@>?P\/#P,_<SQ\'(!(D#B7,$7UY;7<.4````!P``
M``8`G@````<````&`*L````'````!@"X````!P````8`T0````<````&`-D`
M```'````!@#A````!P````8`Z0````<````&``\!```'````!@`9`0``!P``
M``8`)@$```<````&`#,!```'````!@!,`0``!P````8`5`$```<````&`%P!
M```'````!@!D`0``!P````8`B@$```<````&`)0!```'````!@"A`0``!P``
M``8`K@$```<````&`,<!```'````!@#/`0``!P````8`UP$```<````&`-\!
M```'````!@`%`@``!P````8`#P(```<````&`!P"```'````!@`I`@``!P``
M``8`0@(```<````&`$H"```'````!@!2`@``!P````8`6@(```<````&`(`"
M```'````!@"*`@``!P````8`EP(```<````&`*0"```'````!@"]`@``!P``
M``8`Q0(```<````&`,T"```'````!@#5`@``!P````8`^P(```<````&``4#
M```'````!@`2`P``!P````8`'P,```<````&`#@#```'````!@!``P``!P``
M``8`2`,```<````&`%`#```'````!@!V`P``!P````8`@`,```<````&`(T#
M```'````!@":`P``!P````8`LP,```<````&`+L#```'````!@##`P``!P``
M``8`RP,```<````&`/$#```'````!@#[`P``!P````8`"`0```<````&`!4$
M```'````!@`N!```!P````8`-@0```<````&`#X$```'````!@!&!```!P``
M``8`;`0```<````&`'8$```'````!@"#!```!P````8`D`0```<````&`*D$
M```'````!@"Q!```!P````8`N00```<````&`,$$```'````!@#G!```!P``
M``8`\00```<````&`/X$```'````!@`+!0``!P````8`)`4```<````&`"P%
M```'````!@`T!0``!P````8`/`4```<````&`&(%```'````!@!L!0``!P``
M``8`>04```<````&`(8%```'````!@"?!0``!P````8`IP4```<````&`*\%
M```'````!@"W!0``!P````8`W04```<````&`.<%```'````!@#T!0``!P``
M``8``08```<````&`!H&```'````!@`B!@``!P````8`*@8```<````&`#(&
M```'````!@!8!@``!P````8`8@8```<````&`&\&```'````!@!\!@``!P``
M``8`E08```<````&`)T&```'````!@"E!@``!P````8`K08```<````&`-,&
M```'````!@#=!@``!P````8`Z@8```<````&`/<&```'````!@`0!P``!P``
M``8`&`<```<````&`"`'```'````!@`H!P``!P````8`3@<```<````&`%@'
M```'````!@!E!P``!P````8`<@<```<````&`(L'```'````!@"3!P``!P``
M``8`FP<```<````&`*,'```'````!@#)!P``!P````8`TP<```<````&`.`'
M```'````!@#M!P``!P````8`!@@```<````&``X(```'````!@`6"```!P``
M``8`'@@```<````&`$D(```'````!@!3"```!P````8`8`@```<````&`&T(
M```'````!@"&"```!P````8`C@@```<````&`)8(```'````!@">"```!P``
M``8`Q`@```<````&`,X(```'````!@#;"```!P````8`Z`@```<````&``$)
M```'````!@`)"0``!P````8`$0D```<````&`!D)```'````!@`_"0``!P``
M``8`20D```<````&`%8)```'````!@!C"0``!P````8`?`D```<````&`(0)
M```'````!@","0``!P````8`E`D```<````&`+H)```'````!@#$"0``!P``
M``8`T0D```<````&`-X)```'````!@#W"0``!P````8`_PD```<````&``<*
M```'````!@`/"@``!P````8`-0H```<````&`#\*```'````!@!,"@``!P``
M``8`60H```<````&`'(*```'````!@!Z"@``!P````8`@@H```<````&`(H*
M```'````!@"P"@``!P````8`N@H```<````&`,<*```'````!@#4"@``!P``
M``8`[0H```<````&`/4*```'````!@#]"@``!P````8`!0L```<````&`"L+
M```'````!@`U"P``!P````8`0@L```<````&`$\+```'````!@!H"P``!P``
M``8`<`L```<````&`'@+```'````!@"`"P``!P````8`I@L```<````&`+`+
M```'````!@"]"P``!P````8`R@L```<````&`.,+```'````!@#K"P``!P``
M``8`\PL```<````&`/L+```'````!@`A#```!P````8`*PP```<````&`#@,
M```'````!@!%#```!P````8`7@P```<````&`&8,```'````!@!N#```!P``
M``8`=@P```<````&`)P,```'````!@"F#```!P````8`LPP```<````&`,`,
M```'````!@#9#```!P````8`X0P```<````&`.D,```'````!@#Q#```!P``
M``8`%PT```<````&`"$-```'````!@`N#0``!P````8`.PT```<````&`%0-
M```'````!@!<#0``!P````8`9`T```<````&`&P-```'````!@"2#0``!P``
M``8`G`T```<````&`*D-```'````!@"V#0``!P````8`SPT```<````&`-<-
M```'````!@#?#0``!P````8`YPT```<````&``T.```'````!@`7#@``!P``
M``8`)`X```<````&`#$.```'````!@!*#@``!P````8`4@X```<````&`%H.
M```'````!@!B#@``!P````8`B`X```<````&`)(.```'````!@"?#@``!P``
M``8`K`X```<````&`,4.```'````!@#-#@``!P````8`U0X```<````&`-T.
M```'````!@`##P``!P````8`#0\```<````&`!H/```'````!@`G#P``!P``
M``8`0`\```<````&`$@/```'````!@!0#P``!P````8`6`\```<````&`'X/
M```'````!@"(#P``!P````8`E0\```<````&`*(/```'````!@"[#P``!P``
M``8`PP\```<````&`,L/```'````!@#3#P``!P````8`@Q````<````&`(T0
M```'````!@":$```!P````8`IQ````<````&`,`0```'````!@#($```!P``
M``8`T!````<````&`-@0```'````!@#^$```!P````8`"!$```<````&`!41
M```'````!@`B$0``!P````8`.Q$```<````&`$,1```'````!@!+$0``!P``
M``8`4Q$```<````&`'D1```'````!@"#$0``!P````8`D!$```<````&`)T1
M```'````!@"V$0``!P````8`OA$```<````&`,81```'````!@#.$0``!P``
M``8`]!$```<````&`/X1```'````!@`+$@``!P````8`&!(```<````&`#$2
M```'````!@`Y$@``!P````8`01(```<````&`$D2```'````!@!O$@``!P``
M``8`>1(```<````&`(82```'````!@"3$@``!P````8`K!(```<````&`+02
M```'````!@"\$@``!P````8`Q!(```<````&`.H2```'````!@#T$@``!P``
M``8``1,```<````&``X3```'````!@`G$P``!P````8`+Q,```<````&`#<3
M```'````!@`_$P``!P````8`91,```<````&`&\3```'````!@!\$P``!P``
M``8`B1,```<````&`*(3```'````!@"J$P``!P````8`LA,```<````&`+H3
M```'````!@#@$P``!P````8`ZA,```<````&`/<3```'````!@`$%```!P``
M``8`'10```<````&`"44```'````!@`M%```!P````8`-10```<````&`%L4
M```'````!@!E%```!P````8`<A0```<````&`'\4```'````!@"8%```!P``
M``8`H!0```<````&`*@4```'````!@"P%```!P````8`UA0```<````&`.`4
M```'````!@#M%```!P````8`^A0```<````&`!,5```'````!@`;%0``!P``
M``8`(Q4```<````&`"L5```'````!@!1%0``!P````8`6Q4```<````&`&@5
M```'````!@!U%0``!P````8`CA4```<````&`)85```'````!@">%0``!P``
M``8`IA4```<````&`,P5```'````!@#6%0``!P````8`XQ4```<````&`/`5
M```'````!@`)%@``!P````8`$18```<````&`!D6```'````!@`A%@``!P``
M``8`1Q8```<````&`%$6```'````!@!>%@``!P````8`:Q8```<````&`(06
M```'````!@",%@``!P````8`E!8```<````&`)P6```'````!@#"%@``!P``
M``8`S!8```<````&`-D6```'````!@#F%@``!P````8`_Q8```<````&``<7
M```'````!@`/%P``!P````8`%Q<```<````&`#T7```'````!@!'%P``!P``
M``8`5!<```<````&`&$7```'````!@!Z%P``!P````8`@A<```<````&`(H7
M```'````!@"2%P``!P````8`N!<```<````&`,(7```'````!@#/%P``!P``
M``8`W!<```<````&`/47```'````!@#]%P``!P````8`!1@```<````&``T8
M```'````!@`X&```!P````8`0A@```<````&`$\8```'````!@!<&```!P``
M``8`=1@```<````&`'T8```'````!@"%&```!P````8`C1@```<````&`+,8
M```'````!@"]&```!P````8`RA@```<````&`-<8```'````!@#P&```!P``
M``8`^!@```<````&```9```'````!@`(&0``!P````8`+AD```<````&`#@9
M```'````!@!%&0``!P````8`4AD```<````&`&L9```'````!@!S&0``!P``
M``8`>QD```<````&`(,9```'````!@"I&0``!P````8`LQD```<````&`,`9
M```'````!@#-&0``!P````8`YAD```<````&`.X9```'````!@#V&0``!P``
M``8`_AD```<````&`"0:```'````!@`N&@``!P````8`.QH```<````&`$@:
M```'````!@!A&@``!P````8`:1H```<````&`'$:```'````!@!Y&@``!P``
M``8`GQH```<````&`*D:```'````!@"V&@``!P````8`PQH```<````&`-P:
M```'````!@#D&@``!P````8`[!H```<````&`/0:```'````!@`:&P``!P``
M``8`)!L```<````&`#$;```'````!@`^&P``!P````8`5QL```<````&`%\;
M```'````!@!G&P``!P````8`;QL```<````&`)4;```'````!@"?&P``!P``
M``8`K!L```<````&`+D;```'````!@#2&P``!P````8`VAL```<````&`.(;
M```'````!@#J&P``!P````8`$!P```<````&`!H<```'````!@`G'```!P``
M``8`-!P```<````&`$T<```'````!@!5'```!P````8`71P```<````&`&4<
M```'````!@"+'```!P````8`E1P```<````&`*(<```'````!@"O'```!P``
M``8`R!P```<````&`-`<```'````!@#8'```!P````8`X!P```<````&``8=
M```'````!@`0'0``!P````8`'1T```<````&`"H=```'````!@!#'0``!P``
M``8`2QT```<````&`%,=```'````!@!;'0``!P````8`@1T```<````&`(L=
M```'````!@"8'0``!P````8`I1T```<````&`+X=```'````!@#&'0``!P``
M``8`SAT```<````&`-8=```'````!@#\'0``!P````8`!AX```<````&`!,>
M```'````!@`@'@``!P````8`.1X```<````&`$$>```'````!@!)'@``!P``
M``8`41X```<````&`'<>```'````!@"!'@``!P````8`CAX```<````&`)L>
M```'````!@"T'@``!P````8`O!X```<````&`,0>```'````!@#,'@``!P``
M``8`\AX```<````&`/P>```'````!@`)'P``!P````8`%A\```<````&`"\?
M```'````!@`W'P``!P````8`/Q\```<````&`$<?```'````!@!M'P``!P``
M``8`=Q\```<````&`(0?```'````!@"1'P``!P````8`JA\```<````&`+(?
M```'````!@"Z'P``!P````8`PA\```<````&`"YF:6QE`````````/[_``!G
M`BY<8W)Y<'1O7&1E<UQA<VU<=VEN,S(N87-M`````````````"YT97AT````
M``````$````#`=PA`````@```````````````"YD871A``````````(````#
M`0`````````````````````````````$```````````````"```````1````
M``````$`(``"```````>````/1````$`(``"```````L````W!\```$`(``"
M```````Z````W"````$`(``"`$@```!?9&5S7U-0=')A;G,`7V1E<U]E;F-R
M>7!T`%]D97-?96YC<GEP=#(`7V1E<U]E;F-R>7!T,P!?9&5S7V1E8W)Y<'0S
!````
`
end

223
lib/des/asm/x86ms.pl Normal file
View File

@@ -0,0 +1,223 @@
#!/usr/local/bin/perl
package x86ms;
$label="L000";
%lb=( 'eax', 'al',
'ebx', 'bl',
'ecx', 'cl',
'edx', 'dl',
'ax', 'al',
'bx', 'bl',
'cx', 'cl',
'dx', 'dl',
);
%hb=( 'eax', 'ah',
'ebx', 'bh',
'ecx', 'ch',
'edx', 'dh',
'ax', 'ah',
'bx', 'bh',
'cx', 'ch',
'dx', 'dh',
);
sub main'LB
{
(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
return($lb{$_[0]});
}
sub main'HB
{
(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
return($hb{$_[0]});
}
sub main'DWP
{
local($addr,$reg1,$reg2,$idx)=@_;
local($t);
local($ret)="DWORD PTR ";
$addr =~ s/^\s+//;
if ($addr =~ /^(.+)\+(.+)$/)
{
$reg2=&conv($1);
$addr="_$2";
}
elsif ($addr =~ /^[_a-zA-Z]/)
{
$addr="_$addr";
}
$reg1="$regs{$reg1}" if defined($regs{$reg1});
$reg2="$regs{$reg2}" if defined($regs{$reg2});
$ret.=$addr if ($addr ne "") && ($addr ne 0);
if ($reg2 ne "")
{
$t="";
$t="*$idx" if ($idx != 0);
$ret.="[$reg2$t+$reg1]";
}
else
{
$ret.="[$reg1]"
}
return($ret);
}
sub main'mov { &out2("mov",@_); }
sub main'movb { &out2("mov",@_); }
sub main'and { &out2("and",@_); }
sub main'or { &out2("or",@_); }
sub main'shl { &out2("shl",@_); }
sub main'shr { &out2("shr",@_); }
sub main'xor { &out2("xor",@_); }
sub main'add { &out2("add",@_); }
sub main'sub { &out2("sub",@_); }
sub main'rotl { &out2("rol",@_); }
sub main'rotr { &out2("ror",@_); }
sub main'exch { &out2("xchg",@_); }
sub main'cmp { &out2("cmp",@_); }
sub main'dec { &out1("dec",@_); }
sub main'jmp { &out1("jmp",@_); }
sub main'je { &out1("je",@_); }
sub main'jz { &out1("jz",@_); }
sub main'push { &out1("push",@_); }
sub main'call { &out1("call",'_'.$_[0]); }
sub out2
{
local($name,$p1,$p2)=@_;
local($l,$t);
print "\t$name\t";
$t=&conv($p1).",";
$l=length($t);
print $t;
$l=4-($l+9)/8;
print "\t" x $l;
print &conv($p2);
print "\n";
}
sub out1
{
local($name,$p1)=@_;
local($l,$t);
print "\t$name\t";
print &conv($p1);
print "\n";
}
sub conv
{
local($p)=@_;
$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
return $p;
}
sub main'file
{
local($file)=@_;
print <<"EOF";
TITLE $file.asm
.386
.model FLAT
EOF
}
sub main'function_begin
{
local($func,$num)=@_;
$params=$num*4;
print <<"EOF";
_TEXT SEGMENT
PUBLIC _$func
EXTRN _des_SPtrans:DWORD
_$func PROC NEAR
push ebp
push ebx
push esi
push edi
EOF
$stack=20;
}
sub main'function_end
{
local($func)=@_;
print <<"EOF";
pop edi
pop esi
pop ebx
pop ebp
ret
_$func ENDP
_TEXT ENDS
EOF
$stack=0;
%label=();
}
sub main'file_end
{
print "END\n"
}
sub main'wparam
{
local($num)=@_;
return(&main'DWP($stack+$num*4,"esp","",0));
}
sub main'wtmp
{
local($num)=@_;
return(&main'DWP($stack+$params+$num*4,"esp","",0));
}
sub main'comment
{
foreach (@_)
{
print "\t; $_\n";
}
}
sub main'label
{
if (!defined($label{$_[0]}))
{
$label{$_[0]}="\$${label}${_[0]}";
$label++;
}
return($label{$_[0]});
}
sub main'set_label
{
if (!defined($label{$_[0]}))
{
$label{$_[0]}="${label}${_[0]}";
$label++;
}
print "$label{$_[0]}:\n";
}
sub main'file_end
{
print "END\n";
}

253
lib/des/asm/x86unix.pl Normal file
View File

@@ -0,0 +1,253 @@
#!/usr/local/bin/perl
package x86ms;
$label="L000";
$align=($main'aout)?"4":"16";
$under=($main'aout)?"_":"";
$com_start=($main'sol)?"/":"#";
if ($main'cpp)
{
$align="ALIGN";
$under="";
$com_start='/*';
$com_end='*/';
}
%lb=( 'eax', '%al',
'ebx', '%bl',
'ecx', '%cl',
'edx', '%dl',
'ax', '%al',
'bx', '%bl',
'cx', '%cl',
'dx', '%dl',
);
%hb=( 'eax', '%ah',
'ebx', '%bh',
'ecx', '%ch',
'edx', '%dh',
'ax', '%ah',
'bx', '%bh',
'cx', '%ch',
'dx', '%dh',
);
%regs=( 'eax', '%eax',
'ebx', '%ebx',
'ecx', '%ecx',
'edx', '%edx',
'esi', '%esi',
'edi', '%edi',
'ebp', '%ebp',
'esp', '%esp',
);
sub main'LB
{
(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
return($lb{$_[0]});
}
sub main'HB
{
(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
return($hb{$_[0]});
}
sub main'DWP
{
local($addr,$reg1,$reg2,$idx)=@_;
$ret="";
$addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
$reg1="$regs{$reg1}" if defined($regs{$reg1});
$reg2="$regs{$reg2}" if defined($regs{$reg2});
$ret.=$addr if ($addr ne "") && ($addr ne 0);
if ($reg2 ne "")
{
$ret.="($reg1,$reg2,$idx)";
}
else
{
$ret.="($reg1)"
}
return($ret);
}
sub main'mov { &out2("movl",@_); }
sub main'movb { &out2("movb",@_); }
sub main'and { &out2("andl",@_); }
sub main'or { &out2("orl",@_); }
sub main'shl { &out2("shll",@_); }
sub main'shr { &out2("shrl",@_); }
sub main'xor { &out2("xorl",@_); }
sub main'add { &out2("addl",@_); }
sub main'sub { &out2("subl",@_); }
sub main'rotl { &out2("roll",@_); }
sub main'rotr { &out2("rorl",@_); }
sub main'exch { &out2("xchg",@_); }
sub main'cmp { &out2("cmpl",@_); }
sub main'jmp { &out1("jmp",@_); }
sub main'je { &out1("je",@_); }
sub main'jne { &out1("jne",@_); }
sub main'jnz { &out1("jnz",@_); }
sub main'dec { &out1("decl",@_); }
sub main'push { &out1("pushl",@_); }
sub main'call { &out1("call",$under.$_[0]); }
sub out2
{
local($name,$p1,$p2)=@_;
local($l,$ll,$t);
print "\t$name\t";
$t=&conv($p2).",";
$l=length($t);
print $t;
$ll=4-($l+9)/8;
print "\t" x $ll;
print &conv($p1);
print "\n";
}
sub out1
{
local($name,$p1)=@_;
local($l,$t);
print "\t$name\t";
print &conv($p1);
print "\n";
}
sub conv
{
local($p)=@_;
# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
$p=$regs{$p} if (defined($regs{$p}));
$p =~ s/^([0-9A-Fa-f]+)$/\$$1/;
$p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
return $p;
}
sub main'file
{
local($file)=@_;
print <<"EOF";
.file "$file.s"
.version "01.01"
gcc2_compiled.:
EOF
}
sub main'function_begin
{
local($func,$num)=@_;
$params=$num*4;
$func=$under.$func;
print <<"EOF";
.text
.align $align
.globl $func
EOF
if ($main'cpp)
{ printf("\tTYPE($func,\@function)\n"); }
else { printf("\t.type $func,\@function\n"); }
print <<"EOF";
$func:
pushl %ebp
pushl %ebx
pushl %esi
pushl %edi
EOF
$stack=20;
}
sub main'function_end
{
local($func)=@_;
$func=$under.$func;
print <<"EOF";
popl %edi
popl %esi
popl %ebx
popl %ebp
ret
.${func}_end:
EOF
if ($main'cpp)
{ printf("\tSIZE($func,.${func}_end-$func)\n"); }
else { printf("\t.size\t$func,.${func}_end-$func\n"); }
print ".ident \"desasm.pl\"\n";
$stack=0;
%label=();
}
sub main'wparam
{
local($num)=@_;
return(&main'DWP($stack+$num*4,"esp","",0));
}
sub main'wtmp
{
local($num)=@_;
return(&main'DWP(-($num+1)*4,"esp","",0));
}
sub main'comment
{
foreach (@_)
{
if (/^\s*$/)
{ print "\n"; }
else
{ print "\t$com_start $_ $com_end\n"; }
}
}
sub main'label
{
if (!defined($label{$_[0]}))
{
$label{$_[0]}=".${label}${_[0]}";
$label++;
}
return($label{$_[0]});
}
sub main'set_label
{
if (!defined($label{$_[0]}))
{
$label{$_[0]}=".${label}${_[0]}";
$label++;
}
print ".align $align\n";
print "$label{$_[0]}:\n";
}
sub main'file_end
{
}