Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make MD4ish roles share Sum::MDPad code

  • Loading branch information...
commit 118927107626594db912c2fe6bc39fc997cb2986 1 parent 2fc1a68
@skids authored
Showing with 39 additions and 71 deletions.
  1. +8 −61 lib/Sum/MD.pm6
  2. +31 −10 t/md.t
View
69 lib/Sum/MD.pm6
@@ -49,7 +49,7 @@ $Sum::MD::Doc::synopsis = $=pod[0].content[3..4]>>.content.Str;
=head1 ROLES
-=head2 role Sum::MD4 [ :$mod8 = False ] does Sum
+=head2 role Sum::MD4 [ :$mod8 = False ] does Sum::MDPad
The C<Sum::MD4> parametric role is used to create a type of C<Sum>
that calculates an MD4 message digest.
@@ -77,11 +77,10 @@ $Sum::MD::Doc::synopsis = $=pod[0].content[3..4]>>.content.Str;
=end pod
use Sum;
+use Sum::MDPad;
role Sum::MD4_5 [ :$alg where { $_ eqv [|] <MD5 MD4 MD4ext RIPEMD-128 RIPEMD-160 RIPEMD-256 RIPEMD-320 > } = "MD5",
- :$mod8 = False ] does Sum {
- has $!o is rw = 0;
- has Bool $!final is rw;
+ :$mod8 = False ] does Sum::MDPad[:lengthtype<uint64_le>] {
has @!w is rw; # "Parsed" message gets bound here.
has @!s is rw; # Current hash state. H in specification.
@@ -113,7 +112,6 @@ role Sum::MD4_5 [ :$alg where { $_ eqv [|] <MD5 MD4 MD4ext RIPEMD-128 RIPEMD-160
(0xf0f0f0f0 +& ($_ +< 4)) +|
(0x0f0f0f0f +& ($_ +> 4)) }));
}
- $!final = False;
}
# A moment of silence for the pixies that die every time something
@@ -472,58 +470,12 @@ role Sum::MD4_5 [ :$alg where { $_ eqv [|] <MD5 MD4 MD4ext RIPEMD-128 RIPEMD-160
@!s = 0xffffffff X+& @!s;
}
- # TODO: when role trusts work for private attributes, these first three
- # candidates can be made generic across a main role and the above
- # conglomeration of functions and constant split up into proper subroles.
- multi method do_add (*@addends) {
- sink for (@addends) { self.add($_) }
- }
- multi method do_add ($addend) {
- # TODO: Typed failure here?
- die("Marshalling error. Addends must be Buf with 0..64 bytes.");
- }
- multi method do_add (Buf $block where { -1 < .elems < 64 },
- Bool $b7?, Bool $b6?, Bool $b5?, Bool $b4?,
- Bool $b3?, Bool $b2?, Bool $b1?) {
- my int $bits = 0;
- my int $byte = 0;
-
-# $block.gist.say;
-
- # Count how many stray bits we have and build them into a byte
- ( $byte = $byte +| (+$_ +< (7 - (($bits = $bits + 1)-1))) )
- if .defined for ($b7,$b6,$b5,$b4,$b3,$b2,$b1);
-
- # Update the count of the total number of bits sent.
- $!o += $block.elems * 8 + $bits;
- $!o +&= 0xffffffffffffffff;
-
- # Check if buffer, bits, the added 1 bit, and the length fit in block
- if $block.elems * 8 + $bits + 1 + 64 < 513 { # Yes
-
- # Note 1 +< (7 - $bits) just happily also DTRT when !$bits
- self.add(Buf.new($block[],$byte +| 1 +< (7 - $bits),
- 0 xx (55 - $block.elems),
- (255 X+& ($!o X+> (0,8...56)))));
- $!o -= 512; # undo what the other multimethod did.
- }
- else { # No
-
- # So break it into two blocks.
- self.add(Buf.new($block[],$byte +| 1 +< (7 - $bits),
- 0 xx (63 - $block.elems)));
- $!o -= 512; # undo what the other multimethod did.
- self.add(Buf.new(0 xx 56,
- (255 X+& ($!o X+> (0,8...56)))));
- $!o -= 512; # undo what the other multimethod did.
- }
- $!final = True;
- }
multi method do_add (Buf $block where { .elems == 64 }) {
- # We now have a complete block to crunch.
-
-# $block.gist.say;
+ # Update the length count and check for problems via Sum::MDPad
+ given self.pos_block_inc {
+ when Failure { return $_ };
+ }
# Explode the message block into a scratchpad
@@ -537,12 +489,7 @@ role Sum::MD4_5 [ :$alg where { $_ eqv [|] <MD5 MD4 MD4ext RIPEMD-128 RIPEMD-160
self.md5_comp if $alg eqv "MD5";
self.ripe4_comp if $alg eqv ("RIPEMD-128"|"RIPEMD-256");
self.ripe5_comp if $alg eqv ("RIPEMD-160"|"RIPEMD-320");
-
- # Update the size in bits.
- $!o += 512; # spec permits this to wrap for large messages
- $!o +&= 0xffffffffffffffff; # Should go away with sized types
};
- method add (*@addends) { self.do_add(|@addends) }
method finalize(*@addends) {
given self.push(@addends) {
@@ -551,7 +498,7 @@ role Sum::MD4_5 [ :$alg where { $_ eqv [|] <MD5 MD4 MD4ext RIPEMD-128 RIPEMD-160
self.add(self.drain) if self.^can("drain");
- self.add(Buf.new()) unless $!final;
+ self.add(Buf.new()) unless $.final;
:256[ 255 X+& (@!s[] X+> (0,8,16,24)) ]
}
View
41 t/md.t
@@ -90,9 +90,13 @@ given (MD5t.new()) {
is MD5t.new().finalize(Buf.new(97 xx 64)),
0x014842d480b571495a4a0363793f7367,
"MD5 is correct (test vector 1).";
-is MD5t.new().finalize(Buf.new(97 xx 64), Buf.new(97 xx 64), Buf.new(97 xx 56)),
- 0x63642b027ee89938c922722650f2eb9b,
+
+given (MD5t.new()) {
+ .push(Buf.new(97 xx 64));
+ .push(Buf.new(97 xx 64));
+ is .finalize(Buf.new(97 xx 56)), 0x63642b027ee89938c922722650f2eb9b,
"MD5 is correct (test vector 2).";
+}
class r160t does Sum::RIPEMD160[] does Sum::Marshal::Raw { };
my r160t $r160 .= new();
@@ -110,9 +114,13 @@ given (r160t.new()) {
is r160t.new().finalize(Buf.new(97 xx 64)),
0x9dfb7d374ad924f3f88de96291c33e9abed53e32,
"RIPEMD-160 is correct (test vector 1).";
-is r160t.new().finalize(Buf.new(97 xx 64), Buf.new(97 xx 64), Buf.new(97 xx 56)),
- 0x52a7ad26b98c60e2f14e0863c1b58de525888b11,
+
+given (r160t.new()) {
+ .push(Buf.new(97 xx 64));
+ .push(Buf.new(97 xx 64));
+ is .finalize(Buf.new(97 xx 56)), 0x52a7ad26b98c60e2f14e0863c1b58de525888b11,
"RIPEMD-160 is correct (test vector 2).";
+}
class r128t does Sum::RIPEMD128[] does Sum::Marshal::Raw { };
my r128t $r128 .= new();
@@ -130,10 +138,13 @@ given (r128t.new()) {
is r128t.new().finalize(Buf.new(97 xx 64)),
0x680716ac638f0d601982c696d37e5e56,
"RIPEMD-128 is correct (test vector 1).";
-is r128t.new().finalize(Buf.new(97 xx 64), Buf.new(97 xx 64), Buf.new(97 xx 56)),
- 0x481285089b4b03da9eeffc2721680354,
- "RIPEMD-128 is correct (test vector 2).";
+given r128t.new() {
+ .push(Buf.new(97 xx 64));
+ .push(Buf.new(97 xx 64));
+ is .finalize(Buf.new(97 xx 56)), 0x481285089b4b03da9eeffc2721680354,
+ "RIPEMD-128 is correct (test vector 2).";
+}
class r320t does Sum::RIPEMD320[] does Sum::Marshal::Raw { };
my r320t $r320 .= new();
@@ -146,14 +157,20 @@ given (r320t.new()) {
"RIPEMD-320 of an empty buffer is correct.";
is .Buf.values.fmt("%x"), "22 d6 5d 56 61 53 6c dc 75 c1 fd f5 c6 de 7b 41 b9 f2 73 25 eb c6 1e 85 57 17 7d 70 5a e c8 80 15 1c 3a 32 a0 8 99 b8", "RIPEMD-320 Buf method works";
}
+
# Since it uses the same buffering code as MD4 we don't need to test
# different lengths thoroughly, but a few more test vectors would be good.
is r320t.new().finalize(Buf.new(97 xx 64)),
0x6e815badcf69d2978caf8b8bbaba941239f9847d1ff140062484cb57a0745bccf21c427705fdd30d,
"RIPEMD-320 is correct (test vector 1).";
-is r320t.new().finalize(Buf.new(97 xx 64), Buf.new(97 xx 64), Buf.new(97 xx 56)),
+
+given r320t.new() {
+ .push(Buf.new(97 xx 64));
+ .push(Buf.new(97 xx 64));
+ is .finalize(Buf.new(97 xx 56)),
0x82c5b5ffb960376afb6e21b33bd2367197080dd9724f7e2947e1075347462e603649bca32ad1b824,
"RIPEMD-320 is correct (test vector 2).";
+}
class r256t does Sum::RIPEMD256[] does Sum::Marshal::Raw { };
my r256t $r256 .= new();
@@ -171,10 +188,14 @@ given (r256t.new()) {
is r256t.new().finalize(Buf.new(97 xx 64)),
0x8147678472c129cabb59f57f637c622ccd5707af80a583303e6dde7d0800ced6,
"RIPEMD-256 is correct (test vector 1).";
-is r256t.new().finalize(Buf.new(97 xx 64), Buf.new(97 xx 64), Buf.new(97 xx 56)),
+
+given r256t.new() {
+ .push(Buf.new(97 xx 64));
+ .push(Buf.new(97 xx 64));
+ is .finalize(Buf.new(97 xx 56)),
0x8e7bc719ca3cdbb9411e43f18955a1f305e7643a0ae20a7a01823e80090fcf37,
"RIPEMD-256 is correct (test vector 2).";
-
+}
class MD2t does Sum::MD2 does Sum::Marshal::Raw { };
my MD2t $s2 .= new();
Please sign in to comment.
Something went wrong with that request. Please try again.