MD4: Difference between revisions

Content added Content deleted
(→‎{{header|Raku}}: use native types)
(Undo revision 356315 by Grondilu (talk) on second thought this code may be wrong)
Line 1,982:
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub md4($str) {
my $@buf = $str.encodeords;
my (&f, &g, &h, &r)$buflen = @buf.elems;
{ $^x +& $^y +| +^$x +& $^z },
{ $^x +& $^y +| $x +& $^z +| $y +& $z },
{ $^x +^ $^y +^ $^z },
# for some reason we have to type v here
-> uint32 $v, $s { $v +< $s +| $v +> (32 - $s) }
 
my \mask = (1 +< 32) - 1;
sub pack-le (@a) { @a.rotor(4).map: {:256[.reverse]} }
my &f = -> $x, $y, $z { ($x +& $y) +| ($x +^ mask) +& $z }
my &g = -> $x, $y, $z { ($^x +& $^y) +| ($x +& $^z) +| ($y +& $z) },
my &h {= -> $^x +&, $^y, +|$z { +^$x +&^ $y +^ $z },
my &r = -> uint32 $v, $s { (($v +< $s) +& mask) +| (($v +& mask) +> (32 - $s)) }
 
sub pack-le (@a) {
gather for @a -> $a,$b,$c,$d { take $d +< 24 + $c +< 16 + $b +< 8 + $a }
}
my uint32 ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
my $term = False;
my $last = False;
formy @$buf.rotor(64,off :partial)= {0;
repeat until $last {
my @block = @buf[$_off..$off+63]:v; $off += 64;
my uint32 @x;
given +@block {
when 64 { @x = pack-le @block }
@x = pack-le when 56..63 {@block;
}
$term = True;
when 56..63 {
@block.push(0x80);
$term = @block.push(slip 0 xx 63 - $_)True;
@x = pack-le @block.push(0x80);
@block.push(slip 0 xx 63 }- $_);
@x = pack-le when 0..55 {@block;
}
@block.push($term ?? 0 !! 0x80);
when 0..55 {
@block.push(slip 0 xx 55 - $_);
@block.push($term ?? 0 !! @x = pack-le @block0x80);
@block.push(slip 0 xx 55 - $_);
my uint32 $bit_len@x = $buf.elems +<pack-le 3@block;
@x.push: $bit_len, $bit_len +> 32;
my $bit_len = $lastbuflen =+< True3;
@x.push: $bit_len +& mask, }$bit_len +> 32;
$last = default {!!!}True;
}
default {
die "oops";
}
}
my ($aa, $bb, $cc, $dd) = $a, $b, $c, $d;
for 0, 4, 8, 12 -> $\i {
$a = r($a + f($b, $c, $d) + @x[ $i+0 ], 3);
$d = r($d + f($a, $b, $c) + @x[ $i+1 ], 7);
$c = r($c + f($d, $a, $b) + @x[ $i+2 ], 11);
$b = r($b + f($c, $d, $a) + @x[ $i+3 ], 19);
}
}
for 0, 1, 2, 3 -> $\i {
$a = r($a + g($b, $c, $d) + @x[ $i+0 ] + 0x5a827999, 3);
$d = r($d + g($a, $b, $c) + @x[ $i+4 ] + 0x5a827999, 5);
$c = r($c + g($d, $a, $b) + @x[ $i+8 ] + 0x5a827999, 9);
$b = r($b + g($c, $d, $a) + @x[ $i+12] + 0x5a827999, 13);
}
}
for 0, 2, 1, 3 -> $\i {
$a = r($a + h($b, $c, $d) + @x[ $i+0 ] + 0x6ed9eba1, 3);
$d = r($d + h($a, $b, $c) + @x[ $i+8 ] + 0x6ed9eba1, 9);
$c = r($c + h($d, $a, $b) + @x[ $i+4 ] + 0x6ed9eba1, 11);
$b = r($b + h($c, $d, $a) + @x[ $i+12] + 0x6ed9eba1, 15);
}
}
$a = ($a,$b,$c,$d) Z[+=] ($aa,$bb,$cc,$dd) +& mask;
$b = ($b + $bb) +& mask;
$c = ($c + $cc) +& mask;
$d = ($d + $dd) +& mask;
}
my buf8sub b2l($abcdn is .=copy) new;{
my $x = 0;
for $a, $b, $c, $d { $abcd.write-uint32: 4*$++, $_, LittleEndian }
for ^4 {
:256[@$abcd];
$x +<= 8;
{ $^x +^= $^yn +^ $^z& },0xff;
$n +>= 8;
}
$x;
}
 
b2l($a) +< 96 +
b2l($b) +< 64 +
b2l($c) +< 32 +
b2l($d);
}