TBS sign


TBS digest, sign.
La firma de autenticación (según se entiende en la Directiva Europea) se propone de esta forma rudimentaria. Fue presentado al congreso de Criptología y Seguridad en la Información de Oviedo 5-7 Sept. 2002 (RECSI7). No contiene (aún) verificación ni IDs.



#!/usr/bin/perl package TBS; # use integer; # Perl compilado con 64bit int para compatibilidad use strict; my $VERSION = '0.91'; my $DEBUG =0; # NO DEBUG my @skeys =(0x0002, 0x0003, 0x0005, 0x0007, 0x0011, 0x0013, 0x0017, 0x0019, 0x1002, 0x1003, 0x1005, 0x1007, 0x1011, 0x1013, 0x1017, 0x1019, 0x1400, 0x1405, 0x1500, 0x1070, 0x1097, 0x1099, 0x1990, 0x3333, 0xaaa6, 0x9876, 0x9631, 0x9110, 0x8755, 0x8888, 0x8242, 0x7411, 0xbaba, 0xaf01, 0xaf77, 0xad48, 0xad43, 0xac57, 0xac42, 0xab69, 0xbbbb, 0xbbb1, 0xbb92, 0xbb38, 0xbb36, 0xbb17, 0xbb00, 0xb000, 0xcb01, 0xcb03, 0xcb05, 0xcb07, 0xcb11, 0xcb13, 0xcb17, 0xcb19, 0xff02, 0xff03, 0xff05, 0xff07, 0xff11, 0xff13, 0xff17, 0xff19); my $num = scalar (@ARGV); my (@data,@x,@atad); # declaration of matrixes (lists). data and x are temporal if ($num <=0) { while ( < STDIN > ){ push @data,$_; last unless $_; } }else{ open (IN,"<".$ARGV[0]) || die "Cannot open $ARGV[0]"; @data = < IN >; close (IN); } unless (@data){ die "Cannot read anything from stdin"; } if ($DEBUG){ print "ok data\n"; } our $unused=""; my $SIGNATURE = &sign_time() . &sign_path_program(); # 7 + 10 if ($DEBUG) { print $SIGNATURE,"\n"; } my ($m,$n,$i,$j,$k)=(0,0,0,0,0); for $i (@data){ $m++; # line if ($m>77){ $m=1; } @x = split "",$i; for $j (@x){ $n++; # column if ($n>77){ $n=1; } $atad[$n][$m] += ord($j); # transpose and acumulate ascii number () } } # @data = (); @x = (); # cleanning $unused .= (ord($j)%100).$m.$n; # get something from size for $i (1..77){ for $j (1..77){ unless (defined $atad[$i][$j]){ # padding if (defined $atad[$j][$i]){ # by the transposed $atad[$i][$j]=$atad[$j][$i]+$i+$j; # sign one-way }else{ # message short $atad[$i][$j] = hex($skeys[($i*77+$j)%64])+$i+$j; } } } } $SIGNATURE .= &sign_studied(@atad); # 17 + 10 if ($DEBUG) { print $SIGNATURE,"\n"; } $SIGNATURE .= &sign_unuseds($unused); # 27 + 10 if ($DEBUG) { print $SIGNATURE,"\n"; } my ($value,$ok,$final,@sol,$z)=(0,0,"",(),0); # declarations. @sol is a small matrix $value=$m+$n; # MD5 2^128=340282366920938463463374607431768211456 # 77^40=2881568890859166525765145719746023659877064263035691961526335443765425482401 for $i (100..140){ # less than 101 for 'warming' $ok=0; while(1) { $value += $i+hex($skeys[$value%64]); # iteration, key, $j=1+$value%77; $k=1+int($value/77)%77; $value += $atad[$j][$k]; # it and its neighbours if (defined $atad[$j-1][$k-1]){ $value += $atad[$j-1][$k-1]; } if (defined $atad[$j+1][$k-1]){ $value += $atad[$j+1][$k-1]; } if (defined $atad[$j-1][$k+1]){ $value += $atad[$j-1][$k+1]; } if (defined $atad[$j+1][$k+1]){ $value += $atad[$j+1][$k+1]; } if ($value<0){ $value= 0; } # if gones overflow... $ok++; last if ($ok==15); # 5*20*40 still < 77*77 matrix (!) } $sol[$i-100]=1+$value%77; } for $i (1..40){ # sol[0] is not used if ($sol[$i]>77 || $sol[$i]<=0){ die "Valor ilegal $sol[$i]\n"; } $z = 45+$sol[$i]; if ($z==96) { $z=45; } # the mouse exception (absent in first bytes) $final .= chr($z); } $SIGNATURE .= $final; # that's all print $SIGNATURE,"\n"; # main END sub sign_time { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $unused .= $mday + $mon + $wday + $isdst; # unused by the moment... my $seconds = $hour*60*60+$min*60+$sec; # seconds goes from 0 to 24*60*60, that is, 86400 # this leads to inefficiency since 77^2 = 5929 and 77^3 = 456533 # so it's a non-sense non using this obvious code: my $byte1 = $hour; my $byte2 = $min; my $byte3 = $sec; $seconds = chr(45+$byte1).chr(45+$byte2).chr(45+$byte3); my $dayoftheyear = $yday; my $byte4 = int ($dayoftheyear/77); my $byte5 = $dayoftheyear % 77; # so dayoftheyear = byte4*77+byte5 $dayoftheyear = chr(45+$byte4).chr(45+$byte5); my $yearsince1900 = $year; my $byte6 = int ($yearsince1900/77); my $byte7 = $yearsince1900 % 77; # so year = byte6*77 +byte7 +1900 $yearsince1900 = chr(45+$byte6).chr(45+$byte7); # putting all together... 7 char, only remains 70... return ($seconds . $dayoftheyear . $yearsince1900); } sub sign_path_program { # PATH is a environment variable, POSIX standard my $path = $ENV{PATH}; # argv[0] contains the program name which signs my $name = $0; my $basestring = ucfirst(lc($path)).uc($name); # lowercase and uppercase # . : ; _ - / and \ are inside base77, but spaces aren't $basestring =~ s/ //g; # uuencoded chars only - don't works, it includes evils \n # $basestring = pack("u",$basestring); # ok this base-string must be no null but could have a lot of chars while (length($basestring)<10){ $basestring .= reverse($basestring); } # so let's truncate to a maximun of 10 chars simply from the left on sequence if (length($basestring)>10){ $unused .= substr($basestring,0,length($basestring)-10,""); } return $basestring; # and remains 60... } sub sign_studied { my @d = @_; # all data from @atad my ($i, $j, $foo, $search, $num); # man sum, cksum, md5sum... for $i (1..77){ for $j (1..77){ # $foo .= $d[$j][$i]; better using XOR as int. op.!!! $num += $d[$i][$j] ^ ($j*$i+$i); # man sum (Sys V 512, BSD 1K) } } ### $checksum = do { local $/; unpack("%32C*",<>) % 65535; }; # rep. Sys V ## $foo =~ s/ //g; # $search = study $foo; # $unused .= $search; # for $i ('0'..'z'){ # $num .= abs(rindex $foo,$i)%10; # } $num = reverse ($num); if (length($num)<10) { $num = 9999999999-$num; } return substr($num,0,10); # only last 50... } sub sign_unuseds { my $s = shift; # reading the variable $unuseds or alike my @s = split "", $s; my $count =""; for (@s){ if (/\d/){ s/(\d)//; $count .= 9-$1; }elsif (/\w/){ s/(\w)//; $count .= ord($1)%100; }else{ s/ //g; $count .= int(length($count)**(4*atan2(1,1))); # powered by PI } } $count =~ s/\D//g; # only digits $count = reverse($count); while (length($count)<10){ $count .= reverse($count); } return substr($count,0,10); # yet remains 40 } 1; __END__


Más información en el Ministerio de Ciencia y Tecnología
Back